用户界面的可配置解决方案
.net的反射以及用户界面的可配置性在一段200行的代码中体现的淋漓尽致。
只需要两个类,两个配置文件。
首先看一下配置文件的结构吧。
ControlColor.xml中定义了控件的名称、种类以及颜色。
<Control>
<ControlType>SwitchTextLabel</ControlType>
<ControlName>TxtPassword</ControlName>
<Color>black,yellow,pink,white</Color>
</Control>
ControlType.xml中定义了控件的类型、颜色属性以及对应的lib库。
<Control>
<ControlType>SwitchTextLabel</ControlType>
<Lib>switchtextlabel.dll</Lib>
<Property>TextBackColor</Property>
<Property>TextForeColor</Property>
<Property>LabelBackColor</Property>
<Property>LabelForeColor</Property>
</Control>
剩余的就是两个类了,其实是很简单的东西。XmlReader就是能把这两个XML文件正确的对应起来并能够准确的取出相应值的类。
重要的是FormUtil这个类。
方法getAllSubControls()就是得到某一个控件内所有的子控件,递归实现的。
看方法setObjProperty。
string type = colorList[0].ToString();2
string[] color = colorList[1].ToString().Split(',');3
string[] property = propertyList[0].ToString().Split(',');4
string lib = propertyList[1].ToString();5

6
Type tp = System.Type.GetType(type);7
if (tp == null)8
{9
Assembly ass = Assembly.LoadFrom(lib);//这个lib就是配置文件ControlType.xml中的Lib10
tp = ass.GetType(type, true, true);11
}12

13
for (int i = 0; i < color.Length; i++)14
{15
if (property.Length > i)16
{17
if (property[i] != "")18
{19
Object[] args = new object[1];20
args[0] = Color.FromName(color[i]);21

22
tp.InvokeMember(property[i], BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty,Type.DefaultBinder, c, args);
23
}24
}25
}26

OK,一切OK。
不过有一点就是需要在每一个Form初始化的时候加上FormUtil的引用,可以说这也是一种装饰模式,保持了一个对Form的引用,但是面向对象的思想继承优先,而不是耦合优先,但是对于已经不能改动的代码这确实是最好的解决办法,如果是可以修改代码呢?抽象父类是否可以更好的解决呢?
这个问题就先放着吧。
已有的解决办法是通过反射实现的,效率可能存在一些问题,但是却是比较好的,因为这样不仅是Color,连别的属性都可以设置,只要再配置文件中做好了配置,并且在FormUtil加入相应的方法,都是可以的。
这确实是一个很不错的解决方案。

浙公网安备 33010602011771号