WPF 字体、颜色等属性的序列化和反序列化

WPF自带的一些属性比如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;
        }
    }

单元测试代码如下:

[Serializable]
    public class SerialMock
    {
        // Private fields.
        string strFirstName = "<first name>";
        DateTime dtBirthDate = new DateTime(1800, 1, 1);
        private FontWeight m_fontWeight = FontWeights.Heavy;

        [XmlElement(ElementName="XAxisProperty_Caption_FontWeight")]
        public FontWeight FontWeight
        {
            get { return m_fontWeight; }
            set { m_fontWeight = value; }
        }

        [XmlElement(ElementName = "XAxisProperty_Caption_FonFamily")]
        private FontFamily m_FontFamily = new FontFamily("TechnicBold");

        public FontFamily FontFamily
        {
            get { return m_FontFamily; }
            set { m_FontFamily = value; }
        }


        public SerialMock()
        {
        
           
        }

        // Public properties.
        public string FirstName
        {
            set
            {
                strFirstName = value;
            }
            get { return strFirstName; }
        }
      
        [XmlElement(DataType = "date")]
        public DateTime BirthDate
        {
            set
            {
                dtBirthDate = value;
            }
            get { return dtBirthDate; }
        }

        public override bool Equals(object obj)
        {
            SerialMock p = obj as SerialMock;
            if (p == null)
            {
                return false;
            }
            return p.FirstName.Equals(this.FirstName)
                && p.BirthDate.Equals(this.BirthDate)
                && p.FontWeight.Equals(this.FontWeight);
        }

        public override int GetHashCode()
        {
            return this.FirstName.GetHashCode() ^ this.BirthDate.GetHashCode() ^ this.FontWeight.GetHashCode();
        }

        public override string ToString()
        {
            return strFirstName.ToArray() + dtBirthDate.ToShortDateString() + FontWeight.ToString() + FontFamily;
        }
    }

 /// <summary>
        ///ReadXml 的测试
        ///</summary>
        [TestMethod()]
        public void ReadXmlTest()
        {
            Property_Setting.Add("People1", new TypeAndValue(typeof(SerialMock), new SerialMock() { FirstName = "a",
                FontWeight = FontWeights.Light, 
                BirthDate=new DateTime(1984, 05, 17)}));
            Property_Setting.Add("People2", new TypeAndValue(typeof(SerialMock), new SerialMock() { FirstName = "b",
                FontWeight = FontWeights.Black,
                FontFamily = new System.Windows.Media.FontFamily("宋体") }));
            MemoryStream stream = new MemoryStream();
            XmlSerializer serializer = new XmlSerializer(typeof(PropertySerializateDictionary));
            serializer.Serialize(stream, Property_Setting);
            stream.Flush();

            stream.Position = 0;
            //stream = new FileStream(System.AppDomain.CurrentDomain.BaseDirectory + "tst.axml", FileMode.Open);
            PropertySerializateDictionary dict = (PropertySerializateDictionary)serializer.Deserialize(stream);
            Assert.AreEqual<PropertySerializateDictionary>(Property_Setting, dict);

            stream.Close();
        }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值