在WinForm開發中,經常會遇到開發雙語版本的問題,利用Resource功能,很容易實現。而前不久,我就遇到了一個難題——枚舉的雙語顯示問題,問題如下:
這裡先定義一個枚舉:
enum Sex
{
Male,
Female
}
然後,我們在WinForm一個視窗中放入一個ComboBox(命名為cbxSex),並把它的資料來源綁定到Sex枚舉,代碼如下:
cbxSex.DataSource = enum.GetValues(typeof(Sex));
此時,介面顯示如下:
但是,此時要做中文版時,發現沒法在不修改cbxSex.DataSource = enum.GetValues(typeof(Sex))的基礎上顯示中文的“男”、“女”。(我要的是能
通過cbxSex.SelectedValue來直接擷取這個枚舉值。)
一個很自然的想法,是實現自訂格式化,即通過IFormatable、IFormatProvider、ICustomFormatter等實現。經查MSDN,發現Enum基類實現了IFormatable,但我這個Sex枚舉好像沒法Override這個IFormatable介面(IFormatable的兩個方法在Enum中都標上了“Obsolete”,估計微軟準備在Enum中去掉IFormatable介面實現吧)。如果通過IFormatProvider、ICustomFormatter來實現,不僅繁瑣不說,而且,ComboBox也沒有一個FormatProvider屬性供設定。因此,問題陷入了一個僵局。(不知道大夥能不能通過這三個介面給出一個比較完美的解決方案。)
最後,我想到一個自覺還不錯的辦法。
既然我要的是能通過cbxSex.SelectedValue來直接擷取這個枚舉值,我何不對Sex枚舉進行下封裝,然後利用ComboBox的DisplayMember和ValueMember屬性來實現雙語顯示呢。想到這裡,我寫了以下這個類:
public class EnumValueStringPair
{
private readonly Enum m_Enum;
public EnumValueStringPair(Enum _enum)
{
this.m_Enum = _enum;
}
/// <summary>
/// 擷取實際的枚舉值。
/// </summary>
public Enum Enum
{
get { return this.m_Enum; }
}
/// <summary>
/// 擷取該枚舉值對應的字串。該欄位從對應的資源檔中提取文本。
/// </summary>
public string EnumString
{
get { return Properties.Resources.ResourceManager.GetString(this.m_Enum.ToString()); }
}
}
在預設資源與中文資源中分別添加兩項,
然後,我在視窗中加入以下兩個靜態自讀欄位
private static readonly EnumValueStringPair m_Male = new EnumValueStringPair(Sex.Male);
private static readonly EnumValueStringPair m_Female = new EnumValueStringPair(Sex.Female);
最後,把cbxSex綁定到這兩個欄位組成的列表中:
List<EnumValueStringPair> list = new List<EnumValueStringPair>();
list.Add(m_Male);
list.Add(m_Female);
this.cbxSex.DataSource = list;
this.cbxSex.DisplayMember = "EnumString";
this.cbxSex.ValueMember = "Enum";
中文效果如下:
至此,雙語版的Enum顯示問題就解決了,而且,如果以後要添加別的語種的Enum顯示,只需添加對應語種的.resx檔案即可,另外,還可以方便的使用cbxSex.SelectedValue來直接擷取Sex枚舉值,也可以直接將cbxSex.SelectedValue設定為Sex.Male或Sex.Female.
後記:
好久好久沒寫過文章了,發現寫得還真有點垃圾,算了,權作為平生第一篇像樣的Blog吧。大家是否有更好的解決辦法,歡迎討論^_^