我如何重新排序这些反序列化的XML节点?

时间:2016-04-07 15:44:59

标签: c# xml wpf datagrid

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

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

我想出了将xml加载到dataGrid中的位置,可以根据我之前提出的问题对其进行编辑。

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

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

Current xml config editor 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>

相关代码的片段处理所有这些:

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语句中,具体取决于用户当前正在查看的元素。任何人都可以看到更简单的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

经过一些挖掘我的代码后,我决定最好的方法是重构我存储配置元素的方式。

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

这样,我可以拥有名为CurrentlySelected的Configurations类的公共成员。每当用户想要查看不同的元素时我会更新。 然后,如果他们想重新排序项目。我只能对CurrentlySelected成员进行更改。

每次我想要一个新的配置元素时,这使我不必添加大量代码。