【问题标题】:Using Multiple XML Documents in a WPF DataGrid在 WPF DataGrid 中使用多个 XML 文档
【发布时间】:2020-10-17 22:10:59
【问题描述】:

所以对于我正在进行的一个项目,我有一个小问题,我不知道如何最好地解决。

原则上,应用程序将首先加载一个 XML 文件,我将始终知道该文件的位置和内容,并将其显示在 DataGrid 中以供用户查看。

然后,用户可以进入应用程序的其他部分,输入他们希望以与原始格式相同的格式导出到 XML 中的数据,但更重要的是这些“编辑”绝不能覆盖原始数据,我将需要将新的输入或编辑保存在单独的 XML 文件中。

我可以很好地处理该部分,但是如果可能的话,我希望 DataGrid 显示两个 XML 文件的组合(并且可能需要能够检查新文件是否重叠并决定要使用哪个文件显示)。

我一直在 WPF 中制作程序,任何想法都会很棒。

谢谢。

【问题讨论】:

  • 网格擅长展示二维数组。所以你必须设计你的 xml 文件,以便数据可以很容易地显示为二维数据。所以我会从设计网格开始。

标签: c# xml wpf


【解决方案1】:

数据网格 - 从 ItemsControl 派生的元素。 所有这些元素仅适用于一个数据源。 数据源必须是 IEnumerable。

您的两个 XML 文件是两个不同的数据源。

我看到了两种解决方案。

创建一个包含两个 DataGrid 的 UserConrol 并同步其中的行滚动。

在 ViewModel 中,从两个源文件创建一个包含两个文件数据的复杂集合。

【讨论】:

    【解决方案2】:

    序列化和反序列化是使用 xml 的简单 csharp 友好方式。

    您希望 xml 在磁盘上,但如果您绑定 ObservableCollection 而不是直接从 xml 绑定某些对象源,您的代码将更容易使用。

    如果这对您来说是一个新概念,请从这里开始阅读:

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/serialization/

    这将涉及序列化一个具有公共属性的类,该公共属性是一个 List,其中 t 是与您的 xml 文件的每个节点对应的类。

    这是一些通用的序列化和反序列化代码:

        public static void saveType<T>(T obj, string fileURL)
        {
            if (!fileURL.EndsWith(".xml"))
            {
                fileURL += ".xml";
            }
            using (FileStream writer = new FileStream(fileURL, FileMode.Create))  // FileMode.Create will over write an existing file
            {
                DataContractSerializer ser = new DataContractSerializer(typeof(T));
                ser.WriteObject(writer, obj);
            }
        }
        public static T readType<T>(string fileURL)
        {
            if (!fileURL.EndsWith(".xml"))
            {
                fileURL += ".xml";
            }
            var deserializedObj = Activator.CreateInstance(typeof(T));
    
            if (!File.Exists(fileURL))
            {
                MessageBox.Show($"No file found at {fileURL}");
                return (T)deserializedObj;
            }
    
            FileStream fs = new FileStream(fileURL, FileMode.Open);
            XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
            DataContractSerializer ser = new DataContractSerializer(typeof(T));
            deserializedObj = (T)ser.ReadObject(reader, true);
            reader.Close();
            fs.Close();
            return (T)deserializedObj;
        }
    
        public static void SaveArmy(string fileURL, Army army)
        {
            saveType<Army>(army, fileURL);
        }
    
        public static Army ReadArmy(string fileURL)
        {
            Army army = readType<Army>(fileURL);
            return army;
        }
    

    您需要做的就是拥有公共属性,不需要任何属性。

    属性本身可以是复杂的对象,因此您可以将列表之类的东西作为每个属性的属性。

    您可能还需要类中的一个属性,您可以使用它来告诉您记录的来源。例如,这是来自原始文件还是从编辑文件中合并。

    使用 Linq 合并您的数据列表。

    例如:

    var combinedList = listOriginal.Union(listNew).ToList();
    

    我不清楚你如何处理组合列表,但这就是你如何将它们合并为一个。

    如果涉及逻辑,您可能会进一步操作该列表并转换为另一个视图模型列表。

    然后您可以将该列表绑定到列表视图或数据网格的项目源。

    在我写这篇文章的时候,我很清楚你没有对你的问题做出解释。我强烈建议您编辑您的帖子并阐明您的要求。因为您的问题很可能会被关闭。

    【讨论】:

      【解决方案3】:

      我决定放弃并改用 2 个数据网格。

      【讨论】:

        猜你喜欢
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 2020-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-12
        • 2011-05-14
        相关资源
        最近更新 更多