最近做一个项目。需要做一个类似VS2003里界面设计器的东西。就是显示一个Panel,可以往上面拖放指定的控件。然后边上得有个PropertyGrid以显示控件的属性。
现在的问题是,代码已经写完了,测试人员突然提出,PropertyGrid里的属性名称最好是中文。而且,某些枚举属性的值在设置的时候也应该显示中文枚举项。
经过一番搜索,在网上发现了Gerd Klevesaat写的Globalized property grid的代码,解决了第一个问题。只是在这里我用了一个二维表,做中文属性名称的转换:
private static string[,] Table = new string[,]
{
{"Location", "位置"}
}
{
{"Location", "位置"}
}
第二个要求就不那么好办了。我以前在MSDN查到一个文章,里面有在PropertyGrid里做下拉框选择属性值的方法。但众所周知,Enum类型的属性不可能是中文。如果换成string,确实可以解决。但是这个属性在程序核心代码里使用比较频繁,这样就需要把整个程序核心从头到尾修改一遍。还无法保证不出问题。
想了想,还是决定玩个技巧:把原来的属性隐藏。新做一个string类型的属性,利用这个属性来实现Enum在PropertyGrid里的中文化(其实就是Internationalized啦!)。这样程序的其他部分都不要动的。只是这个办法是我在大张旗鼓地改了一个属性以后才想到的……
代码如下:
[Description("测试属性"),Category("测试")]
[Editor(typeof(TestEditor),typeof(UITypeEditor))]
public string sTest
{
get
{
return TestEnumName.Table[TestEnumName.IndexOf(Test.ToString()),1];
}
set
{
Test=(TestEnum)Enum.Parse(typeof(TestEnum),TestEnumName.Table[TestEnumName.IndexOf(value),0]);
}
}
[Editor(typeof(TestEditor),typeof(UITypeEditor))]
public string sTest
{
get
{
return TestEnumName.Table[TestEnumName.IndexOf(Test.ToString()),1];
}
set
{
Test=(TestEnum)Enum.Parse(typeof(TestEnum),TestEnumName.Table[TestEnumName.IndexOf(value),0]);
}
}
public enum TestEnum
{
fsNULL,
{
fsNULL,
fsNn
}
}
public class TestEnumName
{
public static string[,] Table = new string[,]
{
{"fsNULL", "无格式"},//0
{"fsNn", "小写数字"},//1
};
{
public static string[,] Table = new string[,]
{
{"fsNULL", "无格式"},//0
{"fsNn", "小写数字"},//1
};
public static int IndexOf(string s)
{
int ret=-1;
{
int ret=-1;
if (s!=null)
{
for(int i = 0; i <= Table.GetUpperBound(0); i++)
{
if((Table[i, 1].Trim().ToLower() == s.Trim().ToLower())||(Table[i, 0].Trim().ToLower() == s.Trim().ToLower()))
{
ret=i;
break;
}
}
}
{
for(int i = 0; i <= Table.GetUpperBound(0); i++)
{
if((Table[i, 1].Trim().ToLower() == s.Trim().ToLower())||(Table[i, 0].Trim().ToLower() == s.Trim().ToLower()))
{
ret=i;
break;
}
}
}
return ret;
}
}
}
}
由于本人一向懒惰,喜欢copy&paste,所以特意把上面的代码写成通用的。需要修改的只有枚举类型的说明和对照表,当然还有类型、属性的名称。
参考文献: