Hot Keys


Hot keys represent a particularly awkward problem for localization. A hot key is a key that is used with the Alt key to jump to or invoke a control on a form or Web page. Both Windows Forms applications and ASP.NET applications suffer the same problem with a similar solution, so we start by looking at the problem from the viewpoint of a Windows Forms application and then cover it again briefly for ASP.NET applications. Figure 8.14 shows a form that has hot keys (the hot keys are visible only when the Alt key is pressed). The hot keys are the underlined letters.

Figure 8.14. Windows Form with Hot Keys


Hot keys represent a localization problem, for several reasons. First, the translator will have trouble choosing a suitable key if the translation tool being used does not show the text in context. For example, if the translator is presented with the finished form as shown in Figure 8.14, the translator can make accurate guesses about the correct hot keys to assign to controls, with little fear of causing a hot key clash with another control. However, if the translator is presented with a stream of phrases out of context, the translator will have little hope of choosing unique hot keys. Second, even if the translator is presented with a visual representation of a form (for example, using WinRes), there is no guarantee that the translator is seeing the complete picture. If the form is combined with other forms or the form is modified programmatically, the translator will not be able to predict the success of the translation choices. Third, there is the problem that most machine translators do not understand that a word with an ampersand (the character used for denoting hot keyse.g., "E&xit") is the same as the word without the ampersand (e.g., "Exit"). As such, your translations will not be successful if the original language has ampersands embedded in the text. Add to this the possibility that the translator can make honest mistakes and accidentally create duplicates (I have done this myself, all too often, even on English-only forms), and the effort involved in choosing and assigning hot keys, and the problem begs for a solution. Enter the HotkeyAssignment class.

The HotkeyAssignment class (included in the source for this book) analyzes controls and performs hot key assignments to controls at runtime according to various rules. Typically, the class would be used in a Form's constructor:

 public Form1() {     InitializeComponent();     HotKeyAssignment.AssignHotKeys(this); } 


To apply this solution to every form, you should create a base form, add the code to the base form's constructor, and ensure that all forms inherit from the base form.

The benefit of this approach is that the analysis and the assignment are performed at runtime: (1) after resources have been loaded and (2) after the form has been fully formed and all of its constituent components are in place. The form shown in Figure 8.14 had its hot keys assigned using the HotKeyAssignment class. The Assign-HotKeys method has a certain level of intelligence built into it. Hot keys are assigned in order of the controls' TabIndexes, with top-level menu items being assigned after all other controls have been assigned. From Figure 18.4, you can see that the "Company" label has been assigned the hot key "C" because it is an obvious choice. However, the "Contact Name" label should not have "C" (for "Contact") assigned because the "C" hot key has already been taken. In this case, the AssignHotKeys method looks at the first letter of other words until it finds an unused letter. In the "Contact Name" example, it chose "N" because it was the first letter of the second word. If an unused hot key cannot be found, it works through every letter of the text until it finds an unused hot key. If the letter "N" had already been taken, it would have chosen "o" because it is the second letter of the word "Contact". If there are no letters in the text that are unused, the next unused letter in the ValidHotKeys array is used.

The AssignHotKeys method has a second overloaded version:

 public static void AssignHotKeys(     Control control, bool preserveExistingHotKeys) 


The preserveExistingHotKeys parameter allows developers to specify whether existing hot keys indicated in the controls' Text property should be preserved. This allows a combination of both approaches: The translator can make some hot key assignments that are critical, or for which the automatic assignment is unacceptable, and the remainder can be handled by the HotKeyAssignment class. So the translator simply handles the exception to the rule rather than laboriously specifying every hot key for every control. The default for this parameter is TRue. If you pass false for preserveExistingHotKeys, the existing hot key assignments are ignored, and are removed and replaced with new hot key assignments.

This strategy solves the problem for individual forms, but it lacks continuity. Because each form is taken in isolation and every control is processed in TabIndex order, there is no guarantee that controls that occur frequently throughout an application will always be assigned the same hot key. This can be quite irritating for a user to have to remember that a button on one form has one hot key, but the same button on another form has a different hot key. The problem is illustrated in Figure 8.14, where the "Office Occupant" check box has taken the hot key "O". A user might have expected the "OK" button to have the hot key "O", but as it occurs later in the tab order, this hot key has already been assigned and the OK button has been assigned the hot key "K". On a different form, it might have been assigned "O", and the user might anticipate this and incorrectly press Alt+O, giving a different result.

For this reason, the HotKeyAssignment class has a StandardHotKeys property and the following overloaded AddStandardHotKey methods:

 public static void AddStandardHotKey(char hotKey) public static void AddStandardHotKey(char hotKey, string text) public static void AddStandardHotKey(StandardHotKey standardHotKey) 


The AddStandardHotKey methods simply provide a convenient way to add new StandardHotKey objects to the StandardHotKeys array property. The Standard-HotKeys property allows developers to "reserve" hot keys and, optionally, their associated text, so that they are not used by other controls. The following code reserves the hot key "O" for the text "OK":

 HotKeyAssignment.AddStandardHotKey('O', "OK"); 


Typically, this code would be executed during application startup. The result is shown in Figure 8.15, where the OK button has been assigned the hot key "O" and the "Office Occupant" check box has had to make do with "F". (Notice the knock-on effect that the Female radio button now has to use "E" instead of "F" because "F" has now been taken.)

Figure 8.15. Windows Form with Hot Keys after "O" Has Been Reserved for "OK"


A variation on this theme is that you can simply reserve various hot keys so that they are not used automatically by HotKeyAssignments:

 HotKeyAssignment.AddStandardHotKey('X'); 


You would do this if you wanted to make sure that X was never automatically assigned to any control (possibly because the translator makes this assignment manually). Of course, the list of standard hot keys and their associated texts are locale specific, so you would need to load them from a resource. A simple way to achieve this is to hold the complete list as a semicolon-delimited string, like this:

 O:OK;X;Y:;C:Cancel 


This list contains four standard hot keys ("O" is for "OK", "X" and "Y" are simply reserved, and "C" is for "Cancel"). To load the complete list, use the HotKeyAssignment.AddStandardHotKeys method:

 HotKeyAssignment.AddStandardHotKeys(     resourceManager.GetString("StandardHotKeys")); 


This assumes that you have created a resource key called StandardHotKeys and that the resourceManager variable or field can retrieve this resource.

Table 8.7 shows HotKeyAssignment's static properties. The Format property allows developers to specify how the hot key should be formatted within the control's text. It is a HotKeyFormat enumeration:

 public enum HotKeyFormat {     Culture, Embedded, SimpleEmbedded,     BracketedSuffix, BracketedPrefix,     BracketedSuffixEmbedded, BracketedPrefixEmbedded}; 


Table 8.7. HotKeyAssignment Static Properties

Property

Description

CultureFormat

The format used to show the hot key in the control's text for the current UI culture

Format

The format used to show the hot key in the control's text

IgnoreAcceptAndCancelButtons

Specifies whether Accept and Cancel buttons should be ignored when assigning hot keys

StandardHotKeys

Array of StandardHotKey objects

ValidHotKeys

Array of valid hot key characters


Embedded means that the hot key is embedded within the words of the control's text. This is the effect seen in Figures 8.14 and 8.15. SimpleEmbedded has the same visual effect, except that the algorithm for assigning the hot key is simpler: It does not attempt to use the first letter of each word first, and simply tries each successive letter in the string. This approach is suitable for languages that typically do not capitalize the first letter of subsequent words. For example, in Swedish, "Contact Name" is "Kontaktens namn". Using a HotKeyFormat of Embedded, the text would be "Kontaktens &namn", giving a hot key of "n". Although this is correct in the form used in this example (because "K" and "O" have already been taken), it does not look correct in Swedish. Instead, it should be "Ko&ntaktens namn" (the underscore appears under the "n" in the first word, not under the "n" in the second word), and this is the effect achieved by SimpleEmbedded.

The Embedded and SimpleEmbedded approaches work well for languages based on a Latin alphabet. They do not work well if your language doesn't use the Latin alphabet. Such languages include Chinese, Japanese, and Korean. These languages still use alpha hot keys, but the hot keys are not normally found within the text. A common solution to this issue is to prefix or suffix the text with a bracketed hot key. The Format property can be set like this:

 HotKeyAssignment.Format = HotKeyFormat.BracketedSuffixEmbedded; 


Figure 8.16 shows the effect of using BracketedSuffixEmbedded on an English form. Note that the resulting text is longer than the original when the hot key is prefixed or suffixed. This may cause the text to be clipped if the controls do not autosize.

Figure 8.16. Windows Form with Hot Keys Using BracketedSuffix HotKeyFormat


The CultureFormat property is a wrapper around the Format property. The purpose of this property is to provide a culture-aware version of the Format property. If Format is Culture (which it is, by default), CultureFormat returns a value that is best suited for the CultureInfo.CurrentUICulture. So if the Current UICulture is Chinese, Japanese, or Korean, and Format is Culture, then CultureFormat returns BracketedSuffixEmbedded. If the CurrentUICulture is Swedish, then CultureFormat returns SimpleEmbedded. If the CurrentUICulture is not Chinese, Japanese, Korean, or Swedish, and Format is Culture, then Culture Format returns Embedded for Windows Forms applications.

The IgnoreAcceptAndCancelButtons Boolean static property allows you to ignore Accept and Cancel buttons when hot keys are being assigned. The default for this property is false, and the result is that these buttons are assigned their own hot keys. However, Microsoft's "Official Guidelines for User Interface Developers and Designers" states that Accept and Cancel buttons should not be assigned their own hot keys (because they already have the Enter and Escape keys assigned, respectively) so if you adhere to these guidelines, you should set this property to TRue.

ASP.NET and Hot Keys

ASP.NET applications have the same hot key issues as Windows Forms applications, with only a few differences. It is worth noting, however, that the prevalence of hot keys in Web applications is much lower than in Windows Forms applications. The requirement to provide support for hot keys in a Web application is much lower, and it is possible that this feature can simply be omitted from many Web applications. On the other hand, it should be noted that many projects (especially government projects) have accessibility requirements that demand that hot keys be available.

Although the behaviour of hot keys on a Web page is the same as for a Windows Form, their implementation differs. The ampersand character has no meaning, implied or actual, in a Web application, so the "embedded" formats (Embedded, SimpleEmbedded, BracketedSuffixEmbedded, and BracketedPrefixEmbedded) are all meaningless in an ASP.NET application. Instead, the hot key is assigned using the WebControl.AccessKey property. This can be set in the .aspx file:

 <asp:Button  AccessKey="O" runat="server"   Text="OK"></asp:Button> 


or in code:

 OKButton.AccessKey = "O"; 


TextBoxes also have an AccessKey, but in the absence of their own setting, they adopt the AccessKey of the Label immediately before them. In ASP.NET 2.0, the Label class has a new property, AssociatedControlId, which provides a more explicit link between a Label and its associated control instead of the somewhat vague association of "the control that follows the label."

The HotKeyAssignment class can be used in a similar way as for Windows Forms applications and is best placed in the page's Load event:

 private void Page_Load(object sender, System.EventArgs e) {     HotKeyAssignment.AssignHotKeys(this); } 


The default for the CultureFormat property is BracketedSuffix for all cultures. BracketedSuffix is the same as the BracketedSuffixEmbedded member, seen earlier, except that no ampersand character is embedded in the text string (because it is meaningless in a Web application).

Another difference to bear in mind is that the menu is typically provided by the browser, and, like a Windows Forms application, the menu hot keys execute at the same level as hot keys on the page. So Alt+F in English Internet Explorer invokes the File menu. To avoid assigning the hot keys that are already used for Internet Explorer's menu to controls on the page, the list of valid hot keys excludes hot keys that are known to be in use. Here is the ASP.NET HotKeyAssignment static constructor and the InitializeValidHotKeys method:

 static HotKeyAssignment() {     InitializeValidHotKeys(); } protected static void InitializeValidHotKeys() {     ValidHotKeys = new Char[] {         'B', 'C', 'D', 'G', 'I', 'J', 'K', 'L', 'M',         'N', 'O', 'P', 'Q', 'R', 'S', 'U', 'W', 'X', 'Y', 'Z'     }; } 


You would need to set the valid hot keys for different language versions of Internet Explorer and different browsers.




.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