【问题标题】:Deserialize XML nested lists to nested ObservableCollection将 XML 嵌套列表反序列化为嵌套的 ObservableCollection
【发布时间】:2015-02-10 16:50:27
【问题描述】:

我正在构建一个在ObservableCollection 中包含ObservableCollection 的对象。反序列化下面的对象可以正确创建 CustomTab 项的集合,但不能创建 Task 项的集合。

下面显示的代码产生零个Task 项目。如果我将代码更改为:

[XmlElement("Tasks")]          // was "Task" in original code
public ObservableCollectionExtended<UtilitiesTask> TasksCollection

我在 TasksCollection 中获得了一项(应该是 2 或 3 个元素,具体取决于我正在阅读的 CustomTab)。

如何让 TasksCollection 填充相应 Task 根目录下的所有 Task 项目?

注意:为了便于阅读,我已将所有属性简化为 { get; set; }。在代码中,我每个人都会发送任何更改的通知。

我正在使用 ModelBase&lt;&gt; 来自的 SimpleMVVM 框架。

这是我的代码:

CustomTabs.xml

<?xml version="1.0" encoding="utf-8"?>
<CustomTabsConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <CustomTab>
    <Header>88888</Header>
    <TabVisibility>Visible</TabVisibility>
    <Tasks>
        <Task>
            <TaskName>Task 11</TaskName>
        </Task>
        <Task>
            <TaskName>Task 12</TaskName>
        </Task>
    </Tasks>
  </CustomTab>
  <CustomTab>
    <Header>555</Header>
    <TabVisibility>Visible</TabVisibility>
    <Tasks>
        <Task>
            <TaskName>Task 21</TaskName>
        </Task>
        <Task>
            <TaskName>Task 22</TaskName>
        </Task>
        <Task>
            <TaskName>Task 23</TaskName>
        </Task>
    </Tasks>
  </CustomTab>
</CustomTabsConfig>

CustomTabs.xsd

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
  <xs:element name="CustomTabsConfig" type="CustomTabsConfigType"/>

  <xs:complexType name="CustomTabsConfigType">
    <xs:sequence>
      <xs:element type="CustomTabType" name="CustomTab" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="CustomTabType">
    <xs:sequence>
      <xs:element type="xs:int" name="Header"/>
      <xs:element type="xs:string" name="TabVisibility"/>
      <xs:element type="TasksType" name="Tasks"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="TasksType">
    <xs:sequence>
      <xs:element type="TaskType" name="Task" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="TaskType">
    <xs:sequence>
      <xs:element type="xs:string" name="TaskName"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

CustomTabsConfigModel.cs(为简洁而编辑)

[XmlRoot("CustomTabsConfig")]
public class CustomTabsConfigModel : ModelBase<CustomTabsConfigModel>
{
    private ConfigReader<CustomTabsConfigModel> configReader;

    /// <summary>
    /// Create a configuration object bound to "CustomTabs.xml" 
    /// contained in [CommonApplicationData]\[Manufacturer]\[ProductName]
    /// </summary>
    public CustomTabsConfigModel()
    {
    }

    /// <summary>
    /// Create a configuration object bound to the specified file name
    /// contained in [CommonApplicationData]\[Manufacturer]\[ProductName]
    /// </summary>
    /// <param name="fileName"></param>
    public CustomTabsConfigModel(String fileName)
    {
        this.TabsFileName = fileName;
    }


    /// <summary>
    /// Collection of custom tabs
    /// </summary>
    [XmlElement("CustomTab")]
    public ObservableCollection<CustomTab> CustomTabsCollection { get; set; }        

    /// <summary>
    /// Loads Tab info from customtabs.xml file
    /// </summary>
    public Boolean LoadConfig(String customTabsFileName = "CustomTabs.xml")
    {
        // Load tabs file
        configReader = new ConfigReader<CustomTabsConfigModel>(customTabsFileName);

        // if we cannot load the config file then don't do anything else
        if (configReader.Load())
        {
            // update all items from CustomTabs.xml 
            CustomTabsCollection = configReader.Data.CustomTabsCollection;
        }
        else
        {
            Log.Write(LogLevel.Fatal, "Configuration file failed to load.");
            return false;
        }

        return true;
    }
}

CustomTab.cs

    [XmlRoot("CustomTab")]
    public class CustomTab : ModelBase<CustomTab>
    {
        public CustomTab()
        {
            this.Header = "";
            this.TabVisibility = Visibility.Visible;
        }    

        [XmlElement("Header")]
        public String Header { get; set; }

        /// <summary>
        /// Sets the Visibility of the tab
        /// </summary>
        [XmlElement("TabVisibility")]
        public Visibility TabVisibility { get; set; }

        /// <summary>
        /// Collection of Tasks
        /// </summary>
        [XmlElement("Task")]
        public ObservableCollection<UtilitiesTask> TasksCollection { get; set; }

    }

    [XmlRoot("Task")]
    public class UtilitiesTask : ModelBase
    {
        public UtilitiesTask()
        {
            this.TaskName = "";
        }

        [XmlElement("TaskName")]
        public String TaskName { get; set; }            
    }
}

【问题讨论】:

  • 如果解决了,请回答您自己的问题 :)
  • 如果您解决了这个问题,请将您的解决方案作为答案发布,并(现在或以后)接受该答案。
  • 要发布您的解决方案,请参阅Can I answer my own question? 并正确发布。

标签: c# xml observablecollection xml-deserialization


【解决方案1】:

我通过像这样更新TasksCollection 解决了这个问题:

[XmlArray("Tasks")]
[XmlArrayItem("Task", typeof(UtilitiesTask))]
public ObservableCollection<UtilitiesTask> TaskCollection

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多