最近做了一个控件。其中涉及了控件的样式的设置的IDEA。
这个IDEA具体就是想在应用程序放个controltheme.config,里面直接放
<cutegrid BooleanTrue="Y" BooleanFalse=" " CellBorderColor="WhiteSmoke" BorderColor="GhostWhite">
<FooterStyle HorizontalAlign="Center" ForeColor="White" BackColor="SteelBlue"></FooterStyle>
<ItemStyle VerticalAlign="Middle" HorizontalAlign="Center" BackColor="PapayaWhip" ForeOverColor="White"
BackOverColor="IndianRed"></ItemStyle>
<CellAltStyle BackColor="#FFE0C0"></CellAltStyle>
<HeaderStyle HorizontalAlign="Center" ForeColor="White" BackColor="SteelBlue"></HeaderStyle>
<MenuItemStyle ImageUrl="search.gif"></MenuItemStyle>
<PagerStyle HorizontalAlign="Right" ForeColor="White" BackColor="Silver"></PagerStyle>
<MenuStyle BorderStyle="Ridge" CssClass="menutable" CellPadding="4"></MenuStyle>
<DetailStyle BackColor="WhiteSmoke"></DetailStyle>
<PagerStyle HorizontalAlign="Right" ForeColor="White" BackColor="Silver"></PagerStyle>
</cutegrid>
这样的XML。
然后控件在运行的时候,读取这个文件,并且自动把里面的设置加载进来。
这样的话,就不需要在设计的时候复制这些样式了,而且还可以随时更换。
具体的代码只有几十行:
namespace CuteSoft.Grid.Impl
{
using System;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using System.Xml;
internal class ObjectMerger
{
//TODO : Improve Performance
static public void MergeToObject(XmlElement element,object obj)
{
PropertyDescriptorCollection pdc=TypeDescriptor.GetProperties(obj);
foreach(XmlAttribute attr in element.Attributes)
{
PropertyDescriptor pd=pdc[attr.LocalName];
if(pd==null)throw(new Exception("Property Not Found : "+attr.LocalName+" At "+obj.GetType().FullName));
pd.SetValue(obj,ConvertType(attr.Value,pd.PropertyType));
}
foreach(XmlElement elem1 in element.SelectNodes("*"))
{
PropertyDescriptor pd=pdc[elem1.LocalName];
if(pd==null)throw(new Exception("Property Not Found : "+elem1.LocalName+" At "+obj.GetType().FullName));
object oldval=pd.GetValue(obj);
if(oldval==null)//
{
if(pd.IsReadOnly)
return;//IGNORE?
oldval=Activator.CreateInstance(pd.PropertyType);
pd.SetValue(obj,oldval);
MergeToObject(elem1,oldval);
}
else
{
MergeToObject(elem1,oldval);
}
}
}
//TODO : Improve Performance
static object ConvertType(string str,Type dstType)
{
if(dstType==typeof(object)||dstType==typeof(string))
return str;
if(dstType.IsEnum)
{
return Enum.Parse(dstType,str,true);
}
foreach(Type interfacetype in dstType.GetInterfaces())
{
if(interfacetype==typeof(IConvertible))
return Convert.ChangeType(str,dstType);
}
TypeConverter tc=TypeDescriptor.GetConverter(dstType);
if(tc!=null)
{
if(tc.CanConvertFrom(typeof(string)))
return tc.ConvertFrom(str);
}
throw(new Exception("Unable to convert string to type :"+dstType));
}
}
}
里面主要简单地应用类型转换的规则,并没有做优化。
使用方法无非就是想办法加载一个XML文档,然后MergeToObject(xmldoc,mycontrol)就可以了。