现在的位置: 首页 > 综合 > 正文

临时写写的 MergeToObject 静态方法

2013年12月05日 ⁄ 综合 ⁄ 共 3108字 ⁄ 字号 评论关闭

最近做了一个控件。其中涉及了控件的样式的设置的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)就可以了。

抱歉!评论已关闭.