【问题标题】:How would I reorder these deserialized XML nodes?我将如何重新排序这些反序列化的 XML 节点?
【发布时间】:2016-07-28 15:04:18
【问题描述】:

我正在为我的应用程序编写一个(最初)简单的 .xml 配置编辑器。

它从 .xml 文档加载一组特定元素(可从下拉列表中选择),并让用户在 DataGrid 中编辑和添加它们。

我想出了将 xml 加载到 dataGrid 中的方法,可以从我之前提出的问题中对其进行编辑。

我的最后一个障碍是用户可能想要对 DataGrid 中的行重新排序,但我没有找到一个好的方法来做到这一点,而无需编写大量在新节点要更新时必须更新的代码被添加。

用于编辑 .xml 配置文件的当前 GUI。

.xml 配置文件示例:

<?xml version="1.0" encoding="utf-8"?>
<Configurations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<FlameScanners>
    <MenuChoice>Fireye 48PT2 </MenuChoice>
    <Body>Fireye 48PT2 </Body>
    <Cost>0</Cost>
  </FlameScanners>
  <FlameScanners>
    <MenuChoice>Fireye 85 Series </MenuChoice>
    <Body>Fireye 85 Series </Body>
    <Cost>0</Cost>
  </FlameScanners>
  <FlameScanners>
    <MenuChoice>Fireye 95 Series </MenuChoice>
    <Body>Fireye 95 Series </Body>
    <Cost>0</Cost>
  </FlameScanners>
  <FlameScanners>
    <MenuChoice>-by others-</MenuChoice>
    <Body>-by others-</Body>
    <Cost>0</Cost>
  </FlameScanners>
</Configurations>

以及处理所有这些的相关代码的 sn-p:

private Configurations deserializedXML;
public ConfigEditorWindow()
{
    InitializeComponent();
    fillSectionDropdown();
    this.deserializedXML = Deserialize<Configurations>();
}

private void comboBox_Section_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (isComboBoxLoaded == false)
        return;
    switch (comboBox_Section.SelectedValue.ToString())
    {
        case "FlameScanners":
            dataGrid.ItemsSource = deserializedXML.FlameScanners;
            break;
            ...
            ...
            ...
    }
}
private static T Deserialize<T>() where T : new()
{
    // Create an instance of T
    T ReturnListOfT = CreateInstance<T>();

    // Create a new file stream for reading the XML file
    using (FileStream ReadFileStream = new FileStream(ConfigFile, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        // Construct a XmlSerializer and use it  
        // to serialize the data from the stream.
        XmlSerializer SerializerObj = new XmlSerializer(typeof(T));
        try
        {
            // Deserialize the hashtable from the file
            ReturnListOfT = (T)SerializerObj.Deserialize(ReadFileStream);
        }
        catch (Exception ex)
        {
            Console.WriteLine(string.Format("Failed to serialize. Reason: {0}", ex.Message));
        }
    }
    // return the Deserialized data.
    return ReturnListOfT;
}

[XmlRoot(ElementName = "FlameScanners")]
public class FlameScanners
{
    [XmlElement(ElementName = "MenuChoice")]
    public string MenuChoice { get; set; }
    [XmlElement(ElementName = "Body")]
    public string Body { get; set; }
    [XmlElement(ElementName = "Cost")]
    public string Cost { get; set; }
}
... //Repeated for each element in the config file
...
[XmlRoot(ElementName = "Configurations")]
public class Configurations
{

    [XmlElement(ElementName = "Scope")]
    public List<Scope> Scope { get; set; }

    [XmlElement(ElementName = "Company")]
    public List<Company> Company { get; set; }

    [XmlElement(ElementName = "ControlStrategies")]
    public List<ControlStrategies> ControlStrategies { get; set; }

    [XmlElement(ElementName = "CustomerSpecs")]
    public List<CustomerSpecs> CustomerSpecs { get; set; }

    [XmlElement(ElementName = "SystemSpecs")]
    public List<SystemSpecs> SystemSpecs { get; set; }

    [XmlElement(ElementName = "ControlSystem")]
    public List<ControlSystem> ControlSystem { get; set; }

    [XmlElement(ElementName = "CsHw")]
    public List<CsHw> CsHw { get; set; }

    [XmlElement(ElementName = "FlameScanners")]
    public List<FlameScanners> FlameScanners { get; set; }

    [XmlElement(ElementName = "Enclosures")]
    public List<Enclosures> Enclosures { get; set; }

    [XmlElement(ElementName = "Options")]
    public List<Options> Options { get; set; }

    [XmlElement(ElementName = "Documents")]
    public List<Documents> Documents { get; set; }

    [XmlElement(ElementName = "Notes")]
    public List<Notes> Notes { get; set; }
}

重申我的问题;对dataGrid中的某一行重新排序的最佳方法是什么?我知道我必须更改 dataGrid 链接到的数据,所以我想可能会做类似的事情:

if (dataGrid.SelectedItem == null || dataGrid.SelectedIndex <= 0 || dataGrid.SelectedIndex > deserializedXML.Company.Count-1)
                return;
            Company c = deserializedXML.Company[dataGrid.SelectedIndex];
            deserializedXML.Company.RemoveAt(dataGrid.SelectedIndex);
            deserializedXML.Company.Insert(dataGrid.SelectedIndex - 1, c);
            dataGrid.Items.Refresh();

但是,这需要在 switch 语句中,具体取决于用户当前正在查看的元素。谁能看到更简单的方法?

谢谢!

【问题讨论】:

    标签: c# xml wpf datagrid


    【解决方案1】:

    使用集合视图对数据进行排序、分组和过滤。

    您可以在下面找到有关如何实现此目的的完整教程:

    How to: Group, Sort, and Filter Data in the DataGrid Control

    【讨论】:

    • 这可以让我以新的顺序将 XML 保存回文件吗?
    【解决方案2】:

    在对我的代码进行了一些挖掘之后,我决定最好的方法是重组我存储配置元素的方式。

    我没有为每个元素设置不同的类(例如,Scope 类和 Company 类),而是创建了一个可以容纳每个配置元素的类。

    这样,我可以有一个名为 CurrentSelected 的配置类的公共成员。每当用户想要查看不同的元素时,我都会更新它。 然后,如果他们想重新订购商品。我可以对 CurrentSelected 成员进行更改。

    这让我不必在每次需要新的配置元素时添加大量代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多