Introduction

Increasingly more and more applications require localization and globalization. In order to accommodate these requirements a programmer will often have to customize a control in order to meet those requirements.

The Basics

Localization is essentially using the CultureInfo Class and altering the User experience to be better suited for their experience. For example if you write an application that displays a date, if it's Localized it will display the date different depending if the user is using your program in France or in the United States. In the example below (the code can be downloaded here) we create a Locale sensitive Masked Text-box for phone numbers. However, phone numbers is not part of the CultureInfo so we have to create our own implementation.

The idea is to create two dictionaries, one with the phone number formatting with area code and one without. Overriding the OnCreateControl to select the appropriate Mask to apply. I couldn't find a way to get the phone number formatting from the CultrueInfo, it doesn't look like there’s a way. Basically I have the dictionary that you can add full codes, language code only or country code only. It will look for the full code first, if there’s no match it will look for the country code and lastly the language code. Finally if there is no matches on any of the above it will return the entry with the key “”. It’s the default for when globalization is off as well. The property Globalize is intended to be able to disable the globalization just in case.


Resources

Wiki Article on Custom Controls
More on this sample.
Download Source code.


Sample Code

   1:   public class PhoneNumberMaskedTextBox : MaskedTextBox
   2:      {    
   3:          /// <summary>
   4:          /// Indicates if the culture of the OS should be applied
   5:          /// </summary>
   6:          private bool globalize = true;
   7:          /// <summary>
   8:          /// Indicates if the formatting should include the areacode
   9:          /// </summary>
  10:          private AreaCode areaCode = AreaCode.WithAreaCode;
  11:   
  12:         
  13:          /// <summary>
  14:          /// Gets or Sets if the control should globalize according to the OS Culture
  15:          /// </summary>
  16:          public bool Globalize { get { return globalize; } set { globalize = value; } }
  17:          /// <summary>
  18:          /// Gets or Sets if the formatting should include areacode
  19:          /// </summary>
  20:          public AreaCode AreaCode { get { return areaCode; } set { areaCode = value; } }
  21:   
  22:          
  23:          private Dictionary<string, string> formatsWithAreaCode = new Dictionary<string, string>()
  24:          {
  25:              {"US","(000) 000-0000"},
  26:              {"es-VE","(0000) 000,00,00"},
  27:              {"CN","(00) 00000000"},
  28:              {"FR","00 00 00 00 00"},
  29:              {"","(000) 000-0000"}
  30:          };
  31:          private Dictionary<string, string> formatsWithoutAreaCode = new Dictionary<string, string>()
  32:          {
  33:              {"US","000-0000"},
  34:              {"es-VE","000,00,00"},
  35:              {"CN","00000000"},
  36:              {"FR","00 00 00"},
  37:              {"","000-0000"}
  38:          };
  39:          public PhoneNumberMaskedTextBox() : base()
  40:          {
  41:              if (globalize)
  42:                  Culture = System.Threading.Thread.CurrentThread.CurrentCulture;
  43:          }
  44:          protected override void OnCreateControl()
  45:          {
  46:              
  47:              this.Mask = getMask();
  48:              base.OnCreateControl();
  49:          }
  50:          protected string  getMask()
  51:          {
  52:              Dictionary<string, string> dictionaryToUse = new Dictionary<string, string>();
  53:              if (this.AreaCode == PNCControls.AreaCode.WithAreaCode)
  54:                  dictionaryToUse = formatsWithAreaCode;
  55:              else if (this.AreaCode == PNCControls.AreaCode.WithoutAreaCode)
  56:                  dictionaryToUse = formatsWithoutAreaCode;
  57:              if (dictionaryToUse.ContainsKey(Culture.Name))
  58:              {
  59:                  return dictionaryToUse[Culture.Name];
  60:              }
  61:              else if (dictionaryToUse.ContainsKey(Culture.Name.Replace(Culture.TwoLetterISOLanguageName + "-","")))
  62:                 return  dictionaryToUse[Culture.Name.Replace(Culture.TwoLetterISOLanguageName + "-","")];
  63:              else if (dictionaryToUse.ContainsKey(Culture.TwoLetterISOLanguageName))
  64:              {
  65:                  return dictionaryToUse[Culture.TwoLetterISOLanguageName];
  66:              }
  67:              else return dictionaryToUse[""];
  68:          }
  69:      }