Welcome

首页 / 软件开发 / .NET编程技术 / WPF 字体、颜色等属性的序列化和反序列化

WPF 字体、颜色等属性的序列化和反序列化2015-01-28WPF自带的一些属性比如System.Windows.Media.Brush、System.Windows.Media.FontFamily、System.Windows.FontWeight等不具有直接序列化能力,本文针对这一点设计名为PropertySerializateDictionary的类,实现了不同类不同对象公有属性的序列化和反序列化。本类继承于Dictionary<string, TypeAndValue>, IXmlSerializable,调用了自实现类TypeAndValue。

代码:

/// <summary>/// 用于记录对象和类型的类/// 用在PropertySerializateDictionary中/// 单元测试:PropertySerializateDictionaryTest/// </summary>public class TypeAndValue{public TypeAndValue(Type type, object value){Type = type;Value = value;}public TypeAndValue(){ }public Type Type { get; set; }public object Value { get; set; } public override bool Equals(object obj){TypeAndValue tav = obj as TypeAndValue;if (tav == null){return false;} var EqualsMehtod = Type.GetMethod("Equals"); if (tav.Type.FullName == this.Type.FullName&& ((bool)EqualsMehtod.Invoke(tav.Value, new object[]{ this.Value}))){return true;}; return false;}
/// <summary> /// 不同类不同对象公有属性的序列化和反序列化 /// 可序列化、反序列化WPF体系Color、Brush、FontFamily、FontWeight /// 无法识别集合类型与Struct?类型 /// </summary> /// <typeparam name="T"></typeparam> public class PropertySerializateDictionary : Dictionary<string, TypeAndValue>, IXmlSerializable { public System.Xml.Schema.XmlSchema GetSchema() { return null; }public void ReadXml(System.Xml.XmlReader reader) { if (reader.IsEmptyElement) { return; }reader.Read(); string TypeString = reader.GetAttribute("Type");while (reader.NodeType != System.Xml.XmlNodeType.EndElement) { string key = reader.Name;Type tpe = Type.GetType(TypeString); PropertyInfo[] props = tpe.GetProperties();this[key] = new TypeAndValue(tpe, tpe.GetConstructor(new Type[] { }).Invoke(null));if (!reader.IsEmptyElement) { //填充属性值 reader.ReadStartElement(); if (reader.NodeType != System.Xml.XmlNodeType.EndElement) { foreach (PropertyInfo pi in props) { if (pi.PropertyType.FullName == "System.Windows.Media.Brush") { System.Windows.Media.BrushConverter brushConverter = new System.Windows.Media.BrushConverter(); pi.SetValue(this[key].Value, (System.Windows.Media.Brush)brushConverter.ConvertFromString(reader.ReadElementString(pi.Name)), null); //根据属性的类型对读取出来的字符串进行转换 }else if (pi.PropertyType.FullName == "System.Windows.Media.FontFamily") { System.Windows.Media.FontFamilyConverter fontFamilyConverter = new System.Windows.Media.FontFamilyConverter(); pi.SetValue(this[key].Value, (System.Windows.Media.FontFamily)fontFamilyConverter.ConvertFromString(reader.ReadElementString(pi.Name)), null); } else if (pi.PropertyType.FullName == "System.Windows.FontWeight") { System.Windows.FontWeightConverter fontFamilyConverter = new System.Windows.FontWeightConverter(); pi.SetValue(this[key].Value, (System.Windows.FontWeight)fontFamilyConverter.ConvertFromString(reader.ReadElementString(pi.Name)), null); } else { pi.SetValue(this[key].Value, Convert.ChangeType(reader.ReadElementString(pi.Name), pi.PropertyType), null); }} } } reader.Read(); } }public void WriteXml(System.Xml.XmlWriter writer) { if (this.Keys.Count < 1) { return; }foreach (string name in Keys) { TypeAndValue tandv = new TypeAndValue();writer.WriteStartElement(name);if (this.TryGetValue(name, out tandv)) { writer.WriteAttributeString("Type", tandv.Type.FullName); //存储该类型的公有属性 PropertyInfo[] props = tandv.Type.GetProperties();//将对象的每个属性名和属性值写入xml文件中 foreach (PropertyInfo prop in props) { //<属性名>属性值</属性名> writer.WriteElementString(prop.Name, prop.GetValue(tandv.Value, null).ToString()); } } writer.WriteEndElement(); } }public override bool Equals(object obj) { PropertySerializateDictionary dic = obj as PropertySerializateDictionary; if (dic == null) { return false; }if (dic.Count != this.Count) { return false; }foreach (string key in dic.Keys) { if (!this[key].Equals(dic[key])) { return false; } }return true; } }