none
控件PropertyGrid的默认值无法保存到XML中 RRS feed

  • 问题

  • 控件PropertyGrid选项中如果包含默认值,就无法保存到XML。具体情况如下:

    保存到XML的代码:

    Type type = this.PropertyGrid.SelectedObject.GetType();
    StringWriter sw = new StringWriter();
    
    XmlSerializer ser = new XmlSerializer(type);
    
    using (XmlTextWriter writer = new XmlTextWriter(sw))
    {
        writer.Formatting = Formatting.Indented;
        ser.Serialize(writer, this.PropertyGrid.SelectedObject);
    }
    
    XmlDocument xmldoc = new XmlDocument();
    xmldoc.LoadXml(sw.ToString());
    xmldoc.Save(_xmlpath);

    其中控件PropertyGrid的SelectedObject绑定一个类,类其中字段属性的简单如下:

    public class AppSettings
    {
        private int test;
    
        [Category("选项"), DefaultValue(3), DisplayName("测试")]
        public int Test
        {
            get { return test; }
            set { test = value; }
        }
    }

    其中去掉

    DefaultValue(3)

    设置3,怎能保存到XML中,XML如下:

    <?xml version="1.0" encoding="utf-16"?>
    <AppSettings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Test>3</TEST>
    </AppSettings>

    如果留着

    DefaultValue(3)

    设置为3,则整个节点都不会存入到XML中,如下:

    <?xml version="1.0" encoding="utf-16"?>
    <AppSettings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    </AppSettings>
    请教这是为什么?如何才能既有默认值又能让默认值存入到XML中去?正确做法是什么?谢谢!

    努力~


    • 已编辑 zjyh16 2014年5月8日 15:36
    2014年5月8日 15:35

答案

  • Xml序列化时会考虑当前属性的默认值,这个默认值先从XmlSerializer的配置中获取,如果没有配置,则从DefaultValue特性中获取,如果属性值和默认值一致,那么就不会写到xml中。

    我们可以手动设置你的AppSettings类中中的Test所用到的默认值为null,这样就可以强制性地让该属性值写到xml中(因为int值不可能为null,既是说int值永远都不会等于默认值,所以序列化时会一直写入该int),代码如下:

    XmlAttributeOverrides xOver = new XmlAttributeOverrides();
    xOver.Add(typeof(AppSettings), "Test", new XmlAttributes()
    {
        XmlDefaultValue = null
    });
    
    XmlSerializer ser = new XmlSerializer(type, xOver);
    
    using (XmlTextWriter writer = new XmlTextWriter(sw))
    {
        writer.Formatting = Formatting.Indented;
        ser.Serialize(writer, this.PropertyGrid.SelectedObject);
    }

    • 已标记为答案 zjyh16 2014年5月9日 5:12
    2014年5月9日 3:05

全部回复

  • Xml序列化时会考虑当前属性的默认值,这个默认值先从XmlSerializer的配置中获取,如果没有配置,则从DefaultValue特性中获取,如果属性值和默认值一致,那么就不会写到xml中。

    我们可以手动设置你的AppSettings类中中的Test所用到的默认值为null,这样就可以强制性地让该属性值写到xml中(因为int值不可能为null,既是说int值永远都不会等于默认值,所以序列化时会一直写入该int),代码如下:

    XmlAttributeOverrides xOver = new XmlAttributeOverrides();
    xOver.Add(typeof(AppSettings), "Test", new XmlAttributes()
    {
        XmlDefaultValue = null
    });
    
    XmlSerializer ser = new XmlSerializer(type, xOver);
    
    using (XmlTextWriter writer = new XmlTextWriter(sw))
    {
        writer.Formatting = Formatting.Indented;
        ser.Serialize(writer, this.PropertyGrid.SelectedObject);
    }

    • 已标记为答案 zjyh16 2014年5月9日 5:12
    2014年5月9日 3:05
  • 原来如此,多谢帮助,非常感谢!

    努力~

    2014年5月9日 5:12