Click Here to Install Silverlight*
Middle EastChange|All Microsoft Sites
Microsoft

Visual Studio 2005: Developing Arabic Windows Forms applications

Introduction

Windows Forms Controls

Setting RightToLeft according to the UICulture

Changing the Input Language

Text Rendering

Number Substitution


Introduction

You are sometimes faced with some challenges to develop Arabic applications. Most of these issues are due to the fact that Arabic is a right-to-left (rtl) language, where the letters are written from right-to-left, unlike most scripts, where letter are written from left-to-right. I n Visual Studio 2005 we bring you more Arabic and rtl support.

In this paper, you will explore the new enhanced rtl features introduced by Visual Studio 2005. First, we'll highlight the new improved Windows Forms Controls. This includes several interesting properties. Second, we'll examine text rendering in Windows Forms applications.

But before you begin, you need to be familiar with the importance of setting your regional settings in Windows. Especially if you are working in non-Unicode, if your work is only Unicode, then you don't need to worry about these settings. However, in many cases you use non-Unicode data and get puzzled with question marks and garbage characters (high-Ansi). If you are not familiar with the Windows Regional and Languages settings, then please take some time and read about it here Arabic Windows Settings .

Windows Forms Controls

Windows Forms controls are the basic elements of a Windows Applications. You will find improvement in the Windows Forms right-to-left (rtl) features. In new controls, such as the TableLayoutPanel , FlowLayoutPanel , SplitContainer , StatusStrip , ToolStrip and MaskedTextBox etc… there is support for rtl. Simply set RightToLeft =Yes and it would set the reading order, alignment and the layout of these controls. While in existing common controls, such as treeview , Listview , MonthCalendar etc... You have a new property to add the rtl layout. Simply set both RightToLeftLayout =true and RightToLeft =yes and you get full rtl layout, there may be some limitations but the development experience is easier.

RightToLeft and RightToLeftLayout are highlighted in the properties Window

Let's examine the main property rtl support, RightToLeft . The RightToLeft property specifies three main things:

•  First, the reading order is rtl. This is important to determine how neutral and numbers would behave. For example, if the textbox contains some text ending with a colon (":") it would be on the left of the text in case of RightToLeft=Yes but would be on the right otherwise. The same would happen with other neutral characters parentheses, full stop or brackets.

•  Second, the text alignment is on the opposite side. This means if text is "Left" aligned then it would be "Right" aligned for Arabic. Therefore, the TextAlign property shows the opposite value in case of RightToLeft . If you enforce "right" alignment it would be displayed to the "left" and vice versa. The reason for this behavior is that the TextAlign property is based on the "near" and "far" coordinates rather than absolute "left" or "right".

•  Third, the layout of the control might also be affected. This means the UI elements are displayed from the right edge to the left edge instead of placing controls from the left to right.

New controls in Visual Studio 2005 respect the above aspects of the RightToLeft property. However, in some older controls we added a new property to enforce the rtl layout, through RightToLeftLayout property. For more information about the RightToLeftLayout , check this article What is RightToLeftLayout?

The following topics explain how Windows Forms applications support rtl and specifically Arabic in more details.

Container Controls

Container controls are controls that visually contain other controls. For example Panel , GroupBox When you set RightToLeft=Yes to a Panel , GroupBox , TabPages , you set the reading order to rtl but the layout of the controls doesn't change. This is similar to previous versions of Visual Studio .NET.

The following controls don't have rtl layout, when RightToLeft=yes:

•  Panel

•  GroupBox

•  TabPages

•  SplitContainerPanels

You need to rearrange the items in these controls to flow from RightToLeft manually because these controls don't have rtl layout.

This is an example of rearranging the layout of the controls programmatically at runtime, without changing the Form at design-time:

int NumberOfControls = ParentPanel.Controls.Count;
for ( int i=0; i<NumberOfControls;i++)
{
      ParentPanel.Controls[i].Left = ParentPanel.Width -
      (ParentPanel.Controls[i].Left + ParentPanel.Controls[i].Width);
}

This code iterates into all the controls in the ParentPanel and changes their location to be rtl oriented.

For more complex layout scenarios, Windows Forms 2.0, provides SplitContainer , TableLayoutPanel and FlowLayoutPanel . These controls are similar to panel controls to host other controls. The TableLayoutPanel and FlowLayoutPanel controls supply advanced layout engine to handle more sophisticated layout needs.

TableLayoutPanel is similar to the table in html. It allows you to define rows and columns that you can set the size automatically in three ways: AutoSize , Percent and Absolute . You have to be careful when dealing with an empty cell while the size is set to AutoSize .

The TableLayoutPanel supports rtl. Simply, set RightToLeft=Yes and the columns would rearrange from right-to-left. This means, the first column would start from the right and the next column is on its left.

FlowLayoutPanel is more suitable when you want a Form and its controls to resize according to the display area similar to HTML Web pages. You can specify the direction in which the controls should be moved during form resize by setting its FlowDirection property to one of four values: LeftToRight , TopDown , RightToLeft , or BottomUp . Don't be confused of the RightToLeft direction this is not the same as setting RightToLeft =Yes. Setting RightToLeft =Yes also affects the child controls and set it's property as well as affects the reading order of the text in the controls.

Like the TableLayoutPanel , the FlowLayoutPanel also supports rtl. Simply set RightToLeft =Yes and the items would flow from right-to-left even though the FlowDirection is still set to LeftToRight. Actually the FlowDirection is reversed when RightToLeft =Yes, similar to the TextAlign property we discussed earlier.

The SplitContainer provides two panels separated by a movable bar. It is designed to replace the Splitter control and give a richer design-time and run-time experience. In the case of vertical panels, when you set the SplitContainer.RightToLeft=Yes. The Panels are reversed. The First panel is place on the right while the second panel is placed on the left. However, the contents of each panel don't flow from right-to-left. To achieve this you can dock a TableLayoutPanel or a FlowLayoutPanel into these SplitContainer's panels.

This shows the SplitConatiner while RightToLeft=Yes:

The Form

Let's examine the Form. The Form is the main element in your application, which contains your controls. You can add rtl support to your Form by simply setting RightToLeft but you will get a better behavior when you set RightToLeftLayout too, it depends on your needs.

There are simple forms and multiple document interface (MDI) parent form but let's start with the simple Form.

First, check this simple Form, before we add rtl to it.

The original form, before rtl.

Second, let's set RightToLeft to Yes and examine the form:

The Form, when RightToLeft is yes

The result is that the title is aligned to the right but the control boxes are still in the same location as when rtl= no. The containing controls inherit RightToLeft=Yes, if they were set to inherit , which is the default.

Third, let's give it a more advanced rtl look and set RightToLeftLayout to true:

The Form, when RightToLeft is yes and RightToLeftLayout =true

The result is that the title is aligned to the right and the control boxes are displayed in an rtl fashion. In addition to the child's controls are laid from the right to left. However, the containing controls don't inherit the RightToLeftLayout value.

Everyone agrees that the title is much better once you set RightToLeftLayout too but some people may not accept the reordering of the controls. This would depend on your application.

There is a simple workaround to keep your layout and still get an rtl title. You can fill the Form's client area with a Panel, so that it is your controls' parent and so the control's layout would not be affected by setting the RightToLeftLayout property.

This would be final result for your Form:

The Form, When RightToLeft is Yes and RightToLeftLayout =true and a docked Panel containing the controls.

Note: If you added the controls on the Form before the Panel, you may need to manually change the control's parent to the Panel instead of the Form.

Now let's examine the MDI Form. The MDI Form contains child Forms and these Forms are cascaded from left to right by default. To cascade child Forms from the right corner to the left of the parent's form you need to set RightToLeftLayout =true for the child forms too. However, this doesn't mean that the child Forms will inherit the RightToLeftLayout , you need to set this property individually to child Forms.

Note. If you need to set the MDI background image, it's recommended not to set RightToLeftLayout=true .

The figure below shows an MDI Parent form with RightToLeftLayout=true:

Strip Controls

When I talk about Strip controls, I am actually referring to MenuStrip , ToolStrip , StatusStrip , and ContextMenuStrip controls. These replace the troubled MainMenu , ToolBar , StatusBar , and ContextMenu . These controls had numerous problems with rtl support so it's great news you got the new strip controls. Even though MainMenu , ToolBar , StatusBar , and ContextMenu are not included by default in the Visual Studio Toolbox, they are still included in the .NET Framework, primarily for backwards compatibility.

The Strip controls provide a contemporary look of Office 2003 and Windows themes. They all share the same code base and thus provide the same handling to all the Strip controls. In addition to the improved design-time experience and ability to host a rich set of child controls, such as dropdownlists , textboxes and more.

And the main benefit is that they support proper RTL.

When you set RightToLeft=Yes, your strip control items are automatically rearranged from right-to- left. Even more, there is an additional property for the rtl images. RightToLeftAutoMirrorImage resolves common issues with rtl users, who use directional images, an example of directional images are the arrows with next \previous images. In this specific case, you need your image to be mirrored too. This property mirrors automatically the ToolStripItem image when the RightToLeft property is set to Yes . Otherwise it doesn't have an affect on your item.

The ToolStripProgressBar also has the RightToLeftLayout property to se the progress layout properly.

Below is a screenshot of a mirrored Question Mark, after setting RightToLeftAutoMirrorImage = True, while RightToLeft=Yes.

This is the code snippet to mirror the Help image:

// helpToolStripButton
//

this .helpToolStripButton.DisplayStyle = System.Windows.Forms. ToolStripItemDisplayStyle .Image;
this .helpToolStripButton.Image = ((System.Drawing. Image )(resources.GetObject( "helpToolStripButton.Image" )));
this .helpToolStripButton.RightToLeftAutoMirrorImage = true ;
this .helpToolStripButton.Text = "He&lp" ;

MaskedTextBox

The MaskedTextBox class is an enhanced TextBox control that enables you to apply a mask for accepting user input. Mainly, the MaskedTextBox was designed to retain most of the functionality of the Masked Edit control in Visual Basic 6.0.

In addition to this, we have a new property in the MaskedTextBox , the Culture property, this will enable you to select between different masks in different cultures. Try to change the Culture property and check the different masks that you can choose from. Below is a list of masks you can choose from, default culture and Arabic culture:

Culture Masks Date Format
(default) Numeric (5-digits) 12345
Phone Number (574) 555-01234
Phone Number no area code 555-01234
Short date 12/11/2003
Short date and time(US) 12/11/2003 11:20
Social Security number 000-00-1234
Time (European\Military) 23:20
Time (US) 11:20
Zip Code 98052-6399
Arabic Phone Number (012) 345-6789
(ar) Phone Number no area code 123-4567
Short date 26 /10 /2005
Short date and time(US) 26 /10 /2005 11:20
Social Security number 123-45-6789
Time 2:30
Time (24 Hours) 14:30

Note: By default, the culture property is detected from your Windows locale settings. You can change this property as you need.

The default "Short date" mask contains spaces between the number and the slash ("/"). This is to insure that dates are displayed properly, even when the MaskedTextBox is RightToLeft. Check this example of the same date in these different cases:

If you are not satisfied with the default "short date" mask for Arabic cultures, you can specify the traditional "short date" mask or even specify your own mask.

Besides these existing masks, you can also define your own mask depending on your needs, as follows:

maskedTextBox1.Mask = "00000-9999";

Common Controls

Some common controls didn't layout properly, even when you set RightToLeft = Yes. However, now, you can add rtl layout to the following controls by simply setting RightToLeftLayout & RightToLeft :

•  TreeView

•  ListView

•  MonthCalendar

•  DateTimePicker

•  Progressbar

•  TabControl

•  TrackBar

For the above controls, you can set RightToLeftLayout for each control but this property can't be inherited. This might appear more difficult to use than the RightToLeft but for a good cause. There is no illusion that this property is simple and trouble free. It has its limitation and you should be aware of them once you set RightToLeftLayout . For more information refer to the online help.

Another issues, you should be aware that, RightToLeftLayout doesn't have an affect on a control until RightToLeft is set to yes too.

You need to be aware of that the images appear mirrored by default, when you set RightToLeftLayout =true.

For more information about the RightToLeftLayout , check this article What is RightToLeftLayout?


Setting RightToLeft according to the UICulture

When you develop multi-lingual application you are bound to change your Forms direction to rtl programmatically at runtime.

There are several techniques to detect the OS language and display your application with the appropriate language and rtl settings, here are some ideas:

The old technique, you would need to detect your UIculture and change the RightToLeft value accordingly.

public static bool CultureInfoIsRightToLeft()
{
string cultureInfoLanguage = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
return
cultureInfoLanguage == "ar" ||
cultureInfoLanguage == "div" ||
cultureInfoLanguage == "fa" ||
cultureInfoLanguage == "syr" ||
cultureInfoLanguage == " ur " ;
}

In Visual Studio 2005, you have a new property TextInfo.IsRightToLeft that indicates the direction of each culture. This is a simple code snippet to detect the culture direction.

private static bool CultureInfoIsRightToLeft()
{
     return System.Globalization.CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft;
}

Changing the Input Language

Did you ever need to control the input language of your application automatically, without the need for the user to switch the keyboard? This functionality is not new in Visual Studio 2005, but it is interesting to multilingual developers. You can easily set CurrentInputLanguage of your application. In the following example I set the Input Language to the CurrentCulture and in the second line I set it to Arabic ( Egypt ):

[C#]

InputLanguage.CurrentInputLanguage= InputLanguage.FromCulture( Application.CurrentCulture);

InputLanguage .CurrentInputLanguage = InputLanguage .FromCulture( new CultureInfo( "ar-eg" ));

The result of the first line is that the keyboard would be switched to the user culture, while in the second case, the user would use the Arabic keyboard by default. For more info check, InputLanguage.CurrentInputLanguage Property (System.Windows.Forms)


Text Rendering

There are numerous classes presented by GDI+ and GDI for rendering text on Windows Forms. The GDI+ Graphics class has several DrawString methods that allow you to specify various features of text, such as location, bounding rectangle, font, and format. In addition, you can draw and measure text with GDI using the static DrawText and MeasureText methods offered by the TextRenderer class. The GDI methods also allow you to specify location, font, and format.

In the case of RightToLeftLayout is true you should use GDI instead of GDI+. This means, you need to use TextRenderer class to display text, while RightToLeftLayout is true. On the other hand, if you use DrawString the text would be mirrored and not readable. A better incentive to use GDI is that it offers better performance and more accurate text measuring than GDI+.

With the introduction of RightToLeftLayout we need to examine two cases for text display. The first is when RightToLeftLayout=true and the second is when RightToLeftLayout=false.

Let's examine the first case, when RightToLeftLayout is set to true:

•  You don't need to change the coordinates because the origin starts from the rightmost edge instead of the left edge of the drawing area.

•  You don't need to set the rtl TextFormatFlags because they are set by default.

The following code snippets show how to display text when RightToLeftLayout=true and RightToLeft=yes:

[VB]

TextRenderer.DrawText(e.Graphics, " العربية !", Me.Font, New Rectangle(5, 5, 50, 50), SystemColors.ControlText)

[C#]

TextRenderer.DrawText(e.Graphics, " العربية !", this.Font, new Rectangle(5, 5, 50, 50), SystemColors.ControlText);

Let's examine the second case, when RightToLeftLayout is set to false:

•  You need to calculate the correct left edge of your controls. Since the origin is still on the left and not on the right.

•  You need to set the rtl TextFormatFlags because it is not set by default. You need to specify TextFormatFlags.RightToLeft .

The following code snippets show how to display text when RightToLeftLayout=false and RightToLeft=yes:

[VB]

'We have to adjust the left of the drawing rectangle to draw the text in the correct location
'NewLeft = FormWidth - (Left + Width)
TextRenderer.DrawText(e.Graphics, " العربية !", Me.Font, New Rectangle(Me.Width - (5 + 50), 5, 50, 50),
SystemColors.ControlText, TextFormatFlags.RightToLeft)

[C#]

// We have to adjust the left of the drawing rectangle to draw the text in the correct location
//NewLeft = FormWidth - (Left + Width)
TextRenderer.DrawText(e.Graphics, " العربية !", this.Font, new Rectangle(this.Width - (5+50), 5, 50, 50),
SystemColors.ControlText, TextFormatFlags.RightToLeft);


Number Substitution

Let's clarify some terminology before we discuss numbers and digits. In the English language, the digits used: 0, 1, 2, ... 8, 9, are traditionally called Arabic digits. The digits used in Arabic writing are traditionally called Indic digits ( ٠١٢٣٤٥ ... ).

Indic digits are represented by the values U+0660 through U+0669 in Unicode. However it is uncommon to store the Unicode values, we mostly store the Ansi value of the digits and leave it to the OS to display the correct digits according to the system settings. For instance, in Arabic text we would see Indic digits at display only and not stored in Arabic. It was important to store digits in a unified manner for several reasons. For example to perform mathematical calculations and for sorting, etc…

For more information on how to set the digit substitution in Windows XP, check this link http://www.microsoft.com/middleeast/arabicdev/windows/winxp/DigitsSupport.aspx#digit . This option exists in other versions of Windows too.

Windows Forms

The Windows default digit substitution is according to the context of the text. This basically means, the digits will be displayed according to the context they are at, in the middle of English text, 0,1,2 … In the middle of Arabic text ٠ , ١ , ٢ , … .

However, most numbers are displayed alone without text, how would the system decide on the digits to use?

In this case, the digits are based on the RightToLeft property. This means, if RightToLeft =Yes then your digit substitution will be Arabic and display Indic digits. Otherwise the digits are 0,1,2.

GDI+

In case you implement your own drawing, you need to specify how your digits would appear in your DrawString. This is achieved using the StringFormat.SetDigitSubstitution. For more info to this method please refer to the documentation . Below is a code snippet that shows how to display digits using the different enums.

private void IndicDigits_Paint( object sender, PaintEventArgs e)
{
StringFormat StrFormat = new StringFormat ();
int AraLCID = new System.Globalization. CultureInfo ( "ar-eg" ).LCID;
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .National);
e.Graphics.DrawString( "Digit Substitution National 0,1,2,3,4,5,6,7,8,9" , this .Font, new SolidBrush ( this .ForeColor), new PointF (10, 10), StrFormat);
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .Traditional);
e.Graphics.DrawString( "Digit Substitution Traditional 0,1,2,3,4,5,6,7,8,9" , this .Font, new SolidBrush ( this .ForeColor), new PointF (10, 30), StrFormat);
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .None);
e.Graphics.DrawString( "Digit Substitution None 0,1,2,3,4,5,6,7,8,9" , this .Font, new SolidBrush ( this .ForeColor), new PointF (10, 50), StrFormat);
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .User);
e.Graphics.DrawString( "Digit Substitution User 0,1,2,3,4,5,6,7,8,9" , this .Font, new SolidBrush ( this .ForeColor), new PointF (10, 70), StrFormat);
}


©2016 Microsoft Corporation. All rights reserved. Contact Us |Terms of Use |Trademarks |Privacy Statement
Microsoft