65.9K
CodeProject 正在变化。 阅读更多。
Home

在设计时将任何对象数据成员绑定到控件

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (5投票s)

2004年11月9日

5分钟阅读

viewsIcon

41265

downloadIcon

899

在设计时,可将任何对象的任何公共数据成员绑定到控件。

引言

AgConfig 类可在设计时将任何对象的任何公共数据成员绑定到控件。它会自动处理对象数据成员与绑定控件内容之间的同步。

它主要用于简化设置数据的处理和设置窗体的创建。有了这个实用类,可以轻松地

  • 访问对象公共数据成员中的数据
  • 在设计时将对象的公共数据成员绑定到控件
  • 将数据序列化到/从 XML 文件

背景

我一直希望能有一种简单的方法来创建设置窗体并将设置数据存储在文件中。

可以使用 Control.DataBinding 将控件的属性绑定到任何对象的属性。但是,除非该对象是 DataSetDataTableSystem.Data 命名空间中的其他几个类,否则无法在设计时进行此操作。

使用 VS.NET 中的 Microsoft XSD 实用程序,可以轻松地为任何类构造 DataSet。此实用程序使我们能够在设计时将控件绑定到 DataSetDataSet 还提供了一种将内容存储到 XML 文件的简单方法。但以编程方式访问 DataSet 内容比访问对象成员要复杂一些。

如果有一个工具可以自动将对象数据成员与 DataSet 内容同步,那就太好了。这样,我们就可以通过对象的成员以编程方式访问我们的设置,并通过在设计时将对象数据成员绑定到控件来轻松创建设置窗体。

使用代码

AgConfig 类的使用可以分为几个类别

  1. 创建设置类
  2. 从设置类创建 DataSet
  3. 创建设置窗体
  4. 读写 XML 数据

1. 创建设置类

设置数据由我们类的公共数据成员表示,例如 AppData 类,它演示了如何创建嵌套类以将设置分成多个部分,以及如何创建对象数组。请注意数组的创建语法,即使为空,也必须创建 Array 对象。

设置类必须有一个公共的默认构造函数(即没有参数的构造函数),才能被 XmlSelizer 序列化。

public class AppData
{
    public string Text = "Hello there";
    public int Number = 7;
    
    public class Section1Class
    {
        public string Text1 = "Hello there 1";
        public int Number1 = 77;
    }

    public Section1Class Section1 = new Section1Class();

    public class Item
    {
        public int ID;
        public string Name;
    }
    
    public Item[] Items = new Item[] {};
}

也许,将 AppData 类放入单独的类库中是个好主意。

2. 创建 DataSet

要从设置类创建 DataSet,我们可以使用 VS.NET 中的 Microsoft XSD 命令行实用程序。此实用程序读取程序集中的类型信息,因此我们需要先重新生成项目(ConfigTest)。

XSL 实用程序的命令行如下所示

<KBD>xsd configtest.exe /type:AppData</KBD>

运行上述命令后,将在当前目录中创建一个包含 AppData 类型 XSD 架构的 schema0.xsd 文件。通过单击“Project/Add Existing Item...”菜单项将此文件添加到项目中,并为方便起见将其重命名为 AppData.xsd

可以通过双击 Solution Explorer 中的 AppData.xsd 文件,并选中“Schema/Generate Dataset”菜单项来从此架构生成 DataSet

最后,必须设置创建的 DataSettargetNamespaceid 属性,以匹配 AgConfig 类处理它们的方式。将 targetNamespace 设置为“ConfigTest.AppData”(形式为“<application name>.<class name>”)并将 id 设置为“AppDataDataSet”(形式为“<class name>DataSet”)。

3. 创建设置窗体

示例设置窗体包含一个 DataGrid 控件,该控件绑定到窗体上的 AppDataDataSet 组件(通过将 DataSet 组件从工具箱拖出并选择类型化的 AppDataDataSet 来创建)。设置窗体中的以下代码使一切协同工作

private AgConfig AppDataConfig = new AgConfig(Settings.AppData);
// settings form's AgConfig object

以下代码是设置窗体构造函数的一部分。config1 被初始化,以便在绑定到 appDataDataSet1 的控件中所做的更改会自动反映到 Settings.AppData(这是 AppData 类的静态实例)的数据成员中。

AppDataConfig.DataSet = appDataDataSet1;

4. 读写 XML 数据

设置对象数据(Settings.AppData)可以使用 AgCondig 类提供的多种方法从/到 XML 格式读取或写入。(请参阅 ReadFromXmlxxx()WriteToXmlxxx() 方法)。

这是一个序列化 XML 数据的示例

<?xml version="1.0"?>
<AppDataDataSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <AppData>
    <Text>Hello there</Text>
    <Number>7</Number>
    <Section1>
      <Text1>Hello there 1</Text1>
      <Number1>77</Number1>
    </Section1>
    <Items>
      <Item>
        <ID>1</ID>
      </Item>
      <Item>
        <ID>2</ID>
      </Item>
    </Items>
  </AppData>
</AppDataDataSet>

AgConfig 类的其他属性和方法包括

  • XmlExtraTypes

    要序列化的附加对象类型的 Type 数组(有关详细信息,请参阅 XmlSerializer 构造函数)。

  • FileName

    用于存储 XML 数据的文件的完全限定名称。默认情况下,这是应用程序启动目录中的一个文件,其名称为 Data 对象加上“.xml”扩展名。

  • XmlRootName

    用于序列化的根 XML 元素的名称。默认情况下,这是 Data 对象的名称。

  • XmlNamespace

    用于序列化的目标命名空间。默认情况下,这是点分隔的应用程序名称和 Data 对象名称。

  • DataSet

    与此实例关联的 DataSet。默认情况下,这是一个非类型化的 DataSet,其架构从 Data 对象的 XML 数据推断而来。

  • Data

    保存设置数据的实际对象。

  • WriteToXmlFile(string file)

    Data 对象数据序列化到 XML 文件。

  • ReadFromXmlFile(string file)

    从 XML 文件反序列化 Data 对象数据。

  • ReadFromXmlStream(Stream s)

    从流反序列化 Data 对象数据。

  • WriteToXmlStream(Stream s)

    Data 对象数据序列化到流。

  • WriteToDataSet(DataSet ds)

    使用 Data 对象数据填充 DataSet

  • ReadFromDataSet(DataSet ds)

    DataSet 中检索 Data 对象数据。

备注

在绑定到 AgConfig.DataSet 的控件中所做的更改会自动反映到相应的 AgConfig.Data 对象数据成员中。

要将直接对 AgConfig.Data 对象数据成员所做的更改反映到 AgConfig.DataSet 中,必须调用 AgConfig.WriteToDataSet() 方法。

使用 XmlSerializer 来序列化数据。因此,只有公共数据成员会被序列化。 .NET 框架库中的某些类无法以这种方式序列化。例如 Drawing.Color 类,它没有公共数据成员,因此无法使用 XmlSerializer 进行序列化。一种解决方法是创建一个包装类,该类公开非公共属性。另一种方法是向设置类添加一个新属性,该属性将 Color 序列化为字符串,并使用 XmlIgnoreXmlElemrnt 属性来禁用原始属性的序列化并更改新属性的 XML 元素名称。

关注点

关键在于找到一种使用 XmlSerializer 序列化对象的方法,使其能够使用 DataSet.ReadXml() 方法反序列化,反之亦然。

历史

这是初始版本。

© . All rights reserved.