« Education Credits: Beyond the Basics | Best Hoot Features » |
Managing Localization in Combo Boxes
Introduction
This example combines the use of combo boxes, a separate DataSource, and localized string
s for alternate cultures.
Background
Using a combo box, programmers can use a selected item as a variable or parameter within a single method. In other cases, the combo box is a collection of options, each of which executes a different method. The combo box can be populated within the design, or assigned using a DataSource
. Even a simple string
array can be used for that. Processing the selection from the combo box when executing a different method for each combo box entry can be done using the index of the selected item.
string[] special = { "Select", "Vowels", "DoubleI",
"DoubleU", "NoVowels", "Consonants", "QNotU",
"Palins", "HighFives", "HighFours", "NoHooks"};
cboSearch.DataSource = special;
switch (cboSearch.SelectedIndex) {
case 1: btnVowelHeavy_Click(sender, e); break;
...
case 5: btnConsonantDumps_Click(sender, e); break;
...
}
An Alternate
When using the combo box selected index the routine may have to be modified each time a new item is added or items are moved around. If we add an item to the middle of the list, we have to figure out what the item number will be and then change the select
statement. Case 2 may be the new one, so the original case 2 has to be changed to case 3, case 3 to case 4, etc.
To avoid that, it is possible to use the selected item's content. Using the actual string
in the collection is often a clearer way to code.
switch(cboSearch.SelectedText) {
case "Vowels": ...
Thus, case 1 would be replaced with case "Vowels
". Additions to the collection will not require any reordering.
The Challenge
This works well until you have to support localization, that is, present different collections of string
s based on the language selected. The string
used in a switch
statement must be a constant, so you can't use:
switch (cboSearch.SelectedText) {
case rm.GetString("Vowels"): ...
We could go back to using indexes, but we want to avoid going back to that. This is where the CultureCombo
comes in handy. This simple class and the supporting method uses the characteristics of a combo box to create localized strings, while keeping the ability to process the selection using string
identification.
class CultureCombo
{
public string name {get; set;}
public string display {get; set;}
}
Next, you would incorporate the method that processes the array. Using this code, you can then apply that to the combo box.
private List<CultureCombo> comboList(string[] termList)
{
List<CultureCombo> options = new List<CultureCombo>();
foreach (string word in termList)
options.Add(new CultureCombo { name = word, display = rm.GetString(word) });
return options;
}
The code assumes you have created a ResourceManager
called rm
. Replace rm
above with whatever variable you used for the ResourceManager
. In my code, it is represented with the code.
Assembly myAssembly = typeof(Utilities).Assembly;
ResourceManager rm = new ResourceManager("Hoot.Resources.Strings", myAssembly)
Implementation
The first step to using this in a program is to create an array of string
IDs, the string
used to access the culture's translation. If you have incorporated localized string
s, you would already have these. In my example:
string[] special = { "Select", "Vowels",
"DoubleI", "DoubleU", "NoVowels", "Consonants",
"QNotU", "Palins",
"HighFives", "HighFours", "NoHooks"};
Next, use the method to populate the combo box.
searchOptions = comboList(special);
cboSearch.ValueMember = "name";
cboSearch.DisplayMember = "display";
cboSearch.DataSource = searchOptions;
Finally, find the item in the list by looking at the value
(or "name
") of the combo box item:
switch (cboSearch.SelectedValue.ToString())
{
case "Vowels":
btnVowelHeavy_Click(sender, e);
break;
case "Consonants":
btnConsonantDumps_Click(sender, e);
break;
..
}
While the string
presented in the combo box could be "Vowels
", or "Voyelles
" depending on the language, the value is the constant "Vowels
".
Points of Interest
Combo boxes have a DataSource
field, so you can use many different sources to populate the box. They also have separate fields for identifying the option chosen. You can use the SelectedIndex
, as well as the SelectedText
or SelectedValue
. You determine what each represents by modifying the DisplayMember
or ValueMember
field.
List boxes are very similar having the same DataSource
, DisplayMember
, and ValueMember
. You can also change each of them programmatically.
This code is from the program Hoot, a word game study tool I created for Scrabble and Words with Friends players.