Windows Forms Best Practices


This section illustrates best practices that are specific to Windows Forms applications.

Form Layout

The general wisdom on form layout for internationalized Windows Forms applications is to lay out forms so that labels are above the controls to which they refer (see Figure 8.17).

Figure 8.17. Traditional Form Layout Placing Labels above TextBoxes


The reasoning behind this approach is that text tends to expand when translated from English to other languages because English often uses fewer or smaller words. German and Welsh are typical examples of languages that occupy greater screen space than English. For this reason, Labels are placed above TextBoxes so that there is room for expansion of the text without having to move the controls on the form. Of course, there is a limit to how accommodating such a form can be. In Figure 8.17, the "House number / House name" label already occupies 75% of the room allocated to it, so it is possible that a translation would bump into the "City" label on the same line. This approach works reasonably well and is suitable for both the .NET Framework 1.1 and 2.0. It does, however, lead to forms that have room for expansion in which the room isn't always used. In an English form, for example, there may be excessive padding "just in case." As we shall see later in this section, the .NET Framework 2.0 has an alternative solution.

AutoSize

One of the most useful properties for form localization is AutoSize. When this property is set to true, the control automatically resizes to accommodate its contents. This is particularly useful for Label controls that are almost certain to be localized. Place a Label control on a form; if you are using Visual Studio 2003, set Label1.AutoSize to TRue (in Visual Studio 2005, this step is unnecessary); enter some text into Label1.Text; and press Enter. The control will resize. You don't have to use this property, but if you don't, the alternative is either to set the label size to be big enough to cope with all eventualities, or to rely on the localizer to resize the control. The former always has the potential for clipped text, and the latter pushes responsibility onto the translator and potentially changes the role from merely a translator to one of a localizer, entering into the realm of form layout. If you feel that Label.AutoSize should always be set to TRue, see the "Label.AutoSize must be true" rule in Chapter 13, which enforces this.

Label is not the only control that has an AutoSize property. In the .NET Framework 1.1, the controls that have an AutoSize property are Label, RichTextBox, StatusBarPanel, TextBox, ToolBar, and trackBar. In the .NET Framework 2.0, the AutoSize property has been moved down to the Control base class from which all Windows Forms controls inherit. This increased availability of the AutoSize property is excellent for internationalization, but you should be aware of its nature. Although the AutoSize property is present in all controls, it is not appropriate to all controls. A MonthCalendar, for example, cannot realistically behave any differently if its AutoSize property is set to true than the way it behaves when its AutoSize property is set to false. For this reason, the Visual Studio 2005 Form Designer hides the AutoSize properties of controls for which it is inappropriate (see Table 8.8). In addition, although the default value for AutoSize is false, the Visual Studio 2005 Form Designer automatically sets the property to true when specific controls are added to a form (see Table 8.8). The exception to this approach is the MaskedTextBox control, which is new in the .NET Framework 2.0, so it does not have to maintain backward compatibility with the previous version of the framework.

Table 8.8. Windows Forms Common Controls Support for AutoSize Property in Visual Studio 2005

Control

AutoSize Visible in Form Designer

AutoSize Set to TRue by Form Designer

Button

Yes

No

CheckBox

Yes

Yes

CheckedListBox

No

ComboBox

Yes

No

DateTimePicker

No

Label

Yes

Yes

LinkLabel

Yes

Yes

ListBox

No

ListView

No

MaskedTextBox

Yes

Defaults to true

MonthCalendar

No

NumericUpDown

Yes

No

PictureBox

No

ProgressBar

No

RadioButton

Yes

Yes

TReeView

No

WebBrowser

No


In the .NET Framework 2.0, the Form class has an AutoSize property (because it inherits from Control). This is particularly helpful if a Label (or other control) is autosized and the form is not big enough to show the entire contents of the control. Figure 8.18 shows a simplistic form that is wide enough to contain its Label control. Figure 8.19 shows the same form after the label's Text property has changed and the label has autosized, causing the form to autosize as a consequence.

Figure 8.18. Windows Form Containing a Label that Is Smaller than the Form's Width


Figure 8.19. Windows Form Containing a Label that Has Autosized, Causing Its Form to Autosize


AutoSizeMode

The .NET Framework 2.0 introduces a new property, AutoSizeMode, which is an AutoSizeMode enumeration. The AutoSizeMode enumeration has two members: GrowAndShrink and GrowOnly. AutoSizeMode controls the behaviour of the AutoSize property. The following controls implement the AutoSizeMode property:

  • Button

  • DataGridViewColumn

  • Form

  • GroupBox

  • Panel

  • SplitterPanel

  • TabPage

  • ToolStripContentPanel

  • UserControl

The default is GrowOnly. When a control's contents change and AutoSize is TRue, the control grows to accommodate the new contents. If the new contents are smaller than the original contents, however, the control shrinks only if the Auto-SizeMode is GrowAndShrink. Using the GrowOnly option allows developers to lay out a form with controls that have reasonable room for expansion without leaving awkwardly large gaps. The majority of users would see a form with a common layout, but languages that demand larger controls would get larger controls without having to squeeze into too small of a space.

AutoEllipsis

The Button, CheckBox, Label, and RadioButton controls have a new property in the .NET Framework 2.0 called AutoEllipsis, which plays an active role when AutoSize is false. The purpose of this control is to provide an alternative to autosizing by showing an ellipsis (three periods, "...") when there is insufficient room to display the full text. Figure 8.20 shows a form with a button that has the text "This text is too long to be seen completely in this button". The text has been truncated in the display, and the remainder of the text has been replaced with an ellipsis. The full text is still available as a ToolTip.

Figure 8.20. Button with AutoEllipsis Set to True


The benefit of this approach is that the form can remain completely fixed in terms of controls and their positions and sizes, but if the controls are too small to display their text, the form remains usable, albeit in a more limited form. This approach is necessary for skinned applications in which the visual appearance of the form has been sculpted into a precise form, and autosizing and repositioning (see the next section) would destroy the form.

TableLayoutPanel and FlowLayoutPanel

One of the really useful features of HTML in terms of internationalization is that it uses flow layout by default. This means that when the text on a page changes as a consequence of localization, controls are automatically bumped out of the way. To line up controls, developers use an HTML table so that when one label bumps one control out of the way, the other controls that were lined up with it are all bumped to the same relative position. In the .NET Framework 1.1, achieving the same effect in a Windows Forms application requires a fair amount of effort. In the .NET Framework 2.0, however, you can easily achieve the same effect using a TableLayout-Panel control. The TableLayoutPanel is effectively an HTML table control for Windows Forms. The FlowLayoutPanel provides the same "flow layout" behaviour for Windows Forms as flow layout does for HTML (i.e., controls follow on from each other either horizontally or vertically). Although you might use FlowLayout-Panel less frequently than TableLayoutPanel, it can be invaluable in a number of UI scenarios, including providing lists and custom menu controls, auto-relocating panel-like windows, and creating custom toolbar scenarios.

Figure 8.21 shows an English and French version of the same form, with several TableLayoutPanel controls helping resize and reposition controls according to the different sizes of the text controls on the form.

Figure 8.21. TableLayoutPanel Resizing and Repositioning Controls on Localized Forms


You can get a better idea of what's happening on this form by looking at the form in Visual Studio 2005 (see Figure 8.22).

Figure 8.22. TableLayoutPanel in the Form Designer in Visual Studio 2005


There are three TableLayoutPanels on the form:

  • One docked to the top, containing the First Name, Middle Name, and Last Name controls

  • One docked to the bottom, containing the buttons

  • One docked to the client of the GroupBox control, containing the address controls

All of the TextBox controls are anchored to the Left and Right sides of their cells. This means that when the cells containing them are resized, the TextBox controls are also resized. All of the Label controls are anchored to the right side of their cells so that they are always closest to the TextBox control to which they refer. The columns containing Label controls are set to AutoSize. For example, in the top TableLayoutPanel, the leftmost column is set to AutoSize. You can specify how columns should resize by clicking on the ellipsis in the Columns property of the TableLayoutPanel in the Properties Window. When the labels in the column automatically resize because the text has changed, the column containing them will also automatically resize. The columns containing the TextBox controls are all set to Percent. For example, in the top TableLayoutPanel, the rightmost column is set to 100% Percent. This means that the rightmost column will occupy 100 percent of the remaining width of the TableLayoutPanel after all of the other autosize columns have been auto-sized. The TextBox columns of the TableLayoutPanel in the middle of the form are both set to 50% Percent because there are two TextBox columns. If you compare the two forms shown in Figure 8.21, you will see that the label sizes are different and the TextBoxes have automatically resized to a smaller size in the French form, to cope with the change to the labels. The important point is that all of the TextBoxes in the same column have moved and resized, thereby maintaining the symmetry of the form.

There is more good news. Figure 8.23 shows the same English form after the user has resized it.

Figure 8.23. TableLayoutPanel Responding to the Form Being Resized


Notice that the form is still fully functional and usable, but in this scenario, the user had a need for the form to be as small as possible. I am a big believer in letting users use their application in the way they want to use it instead of the way the developer wants them to use it. One of the most frustrating parts of using an application, for me, is to encounter a form that uses a control that should be docked when the control has not been docked. The classic example is a grid control. This control is just begging to the docked to the client of its container. The control resizes perfectly when its container is resized, so there is no reason to stifle users by not allowing them to gain the benefits of resizing the form. The point is that the TableLayout-Panel control takes this attitude to the next level; if users want a very small version of their form, the TableLayoutPanel lets them have it.

Staying on the good news theme, the TableLayoutPanel adopts its Right-ToLeft property (see Chapter 7) from its parent and mirrors its contents correctly when RightToLeft is set to Yes.

The TableLayoutPanel changes the Windows Forms internationalization story. The traditional approach of laying out labels above their respective controls works until the width of the labels exceeds the width allocated to them. The width allocated to them is fixed by the developer in the nature of the form. If the developer calculates this width incorrectly (and developers often use the time-honoured "try it and see" method), either the developer must change the form or the translator takes the responsibility for form layout and takes the more sophisticated role of localizer. With the TableLayoutPanel, developers can craft forms either using the traditional approach of laying out labels above their controls or, alternatively, laying out labels to the left of their controls. Regardless of this decision, there is no danger of overlapping controls and clipped text because the TableLayoutPanel will ensure that controls are moved and resized accordingly. There are several consequences of this. First, the localization effort is lower because localizers will not spend as much time changing form layouts. Second, there is a considerably higher probability of form correctness for all cultures because of the automatic resizing and repositioning. Third, the level of sophistication of the localization tools is lower because localizers may not need to redesign forms. It is still true that a better result will be achieved by allowing translators/localizers to see the form they are translating while they are translating it, just as they can with WinRes, but it strengthens the developer's argument that localizers do not need to resize and reposition controls. If you write a replacement for WinRes, the tool need not be as sophisticated because it would not have to support resizing and repositioning. Finally, the TableLayoutPanel control means that the localization effort is closer to that of translation than localization. The lower level of effort involved and the lower level of sophistication saves time and money, and means that the success of using a bilingual in-house employee who understands the business as opposed to software development is higher. A word of caution, though, lest you conclude that you should always use TableLayoutPanel controls in every scenario: TableLayoutPanel has been written with performance in mind, but don't underestimate the amount of effort that it goes to in order to lay out a form. If you start nesting TableLayoutPanels many levels deep, you can expect to see performance issues.




.NET Internationalization(c) The Developer's Guide to Building Global Windows and Web Applications
.NET Internationalization: The Developers Guide to Building Global Windows and Web Applications
ISBN: 0321341384
EAN: 2147483647
Year: 2006
Pages: 213

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net