【问题标题】:WPF save dataset to xmlWPF 将数据集保存到 xml
【发布时间】:2017-06-13 03:05:44
【问题描述】:

我尝试将 xml 文件读取/保存到数据网格,并且我正在使用数据集来执行此操作。现在我已经成功将xml文件数据加载到datagrid了,代码如下:

public class StoreDbDataSet
{
    internal static DataSet ReadDataSet()
    {
        DataSet ds = new DataSet();
        ds.ReadXmlSchema("store.xsd");
        ds.ReadXml("store.xml");
        return ds;
    }

}

还有:

public class StoreDb
{
    public ObservableCollection<Product> GetProducts()
    {
        DataSet ds = StoreDbDataSet.ReadDataSet();

        ObservableCollection<Product> products = new ObservableCollection<Product>();
        foreach (DataRow productRow in ds.Tables["Products"].Rows)
        {
            products.Add(new Product((string)productRow["ModelNumber"],
                (string)productRow["ModelName"], (string)productRow["InputAddress"],
                (string)productRow["OutputAddress"], (string)productRow["DiagAddress"],
                (string)productRow["Description"], (byte)productRow["CategoryID"],
                (string)productRow["CategoryName"], (string)productRow["ProductImage"]));
        }
        return products;
    }
}

Xaml 文件:

<DataGrid Name="dgBasicInfo" ItemsSource="{Binding ProductsView, Mode=TwoWay}" CanUserResizeColumns="False" AutoGenerateColumns="False" Margin="10,10,10,15" BorderThickness="5" FontSize="14" Background="White">
   <DataGrid.Columns>
       <DataGridTextColumn Header="SlaveId" Binding="{Binding CategoryID}" />
       <DataGridTextColumn Header="ModelName" Binding="{Binding ModelName}"/>
       <DataGridTextColumn Header="CategoryName" Binding="{Binding CategoryName}" />
       <DataGridTextColumn Header="InputAddress" Binding="{Binding InputAddress}" />
       <DataGridTextColumn Header="OutputAddress" Binding="{Binding OutputAddress}" />
       <DataGridTextColumn Header="DiagAddress" Binding="{Binding DiagAddress}" />
       <DataGridTextColumn Header="Specification" Binding="{Binding Description}" />
    </DataGrid.Columns>
</DataGrid>

视图模型:

    public ICollectionView ProductsView
    {
        get { return _ProductsView; }
        set
        {
            _ProductsView = value;
            NotifyPropertyChanged();
        }
    }

我的问题是当我更改数据网格数据时,如何将更改保存到 xml?提前谢谢!

---------------更新------- ------------

    private void RefreshProductList()
    {
        ProductsView = new ListCollectionView(sdb.GetProducts())
        {
            Filter = obj =>
            {
                var Product = (Product)obj;
                return SelectedProduct != null && Product.ModelNumber == SelectedProduct.ModelNumber;
            }
        };
    }

    private Product selectedProduct;
    public Product SelectedProduct
    {

        get { return selectedProduct; }
        set
        {
            if (selectedProduct != value)
            {
                selectedProduct = value;
                NotifyPropertyChanged();
                RefreshProductList();
                RefreshModule();
                RefreshCommunication();
                List<Product> productlist = ProductsView.ToList();
                File.WriteAllText("store.xml", productlist.ToXML());
            }
        }
    }

【问题讨论】:

  • WriteXml 怎么样?
  • 我这样做了,但它只是创建了一个新的空 xml 文件。
  • 您将哪个组件写入 xml?您正在将数据绑定到 ProductsView,请查看那里的 setter 方法的更改。如果更改,则将其写入 XML。
  • 对不起,我已经更新了正确的代码。
  • 好像我在datagrid中更改数据时,System没有在ProductView方法中调用NotifyPropertyChanged

标签: c# xml wpf datagrid dataset


【解决方案1】:

问题是您正在将 xml 作为数据集读取,而不是将其作为产品读取并将其保存为产品数组,如下所示

你的xml格式应该是这样的

<ArrayOfProduct>
<Product>
<ModelNumber>abc</ModelNumber>
//remaking properties 
</Product>
</ArrayOfProduct>

创建一个扩展方法类,这可以帮助您将xml转换为list,反之亦然

public static class ExtensionMethods
{
    /// <summary>
    /// Converts given class to XML using xml serialization
    /// </summary>
    /// <typeparam name="T">Type of Class</typeparam>
    /// <param name="classObject">Class to be serialized</param>
    /// <returns>Xml string</returns>
    public static string ToXML<T>(this T classObject) where T : class
    {
        XmlSerializer xmls = new XmlSerializer(typeof(T));
        using (MemoryStream ms = new MemoryStream())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = new UTF8Encoding(false);
            settings.Indent = true;
            settings.IndentChars = "\t";
            settings.NewLineChars = Environment.NewLine;
            settings.OmitXmlDeclaration = true;
            settings.ConformanceLevel = ConformanceLevel.Document;
            using (XmlWriter writer = XmlTextWriter.Create(ms, settings))
            {
                xmls.Serialize(writer, classObject);
            }

            string xml = Encoding.UTF8.GetString(ms.ToArray());
            return xml;
        }
    }

    /// <summary>
    /// Converts given XML string to class of type T
    /// </summary>
    /// <typeparam name="T">Type to be converted</typeparam>
    /// <param name="XmlData">xml string</param>
    /// <returns>class of Type T</returns>
    public static T ToClass<T>(this string XmlData)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        T newClass;
        using (XmlTextReader reader = new XmlTextReader(new StringReader(XmlData)))
        {
            //reader.Namespaces = false;
            newClass = (T)serializer.Deserialize(reader);
        }
        return newClass;
    }
}

现在您的商店数据库应该如下所示

public class StoreDb
{
    public ObservableCollection<Product> GetProducts()
    {
        string StoreData = string.Empty;
        using(StreamReader sr = new StreamReader("store.xml"))
          {
              StoreData = sr.ReadToEnd();
          }
        ObservableCollection<Product> products = new ObservableCollection<Product>(StoreData.ToClass<List<Product>());

        return products;
    }
}

将 productsView 更改为 observablecollection

private ObservableCollection<Product> _ProductsView;
public ObservableCollection<Product> ProductsView
    {
        get { return _ProductsView; }
        set
        {
            _ProductsView = value;
            NotifyPropertyChanged();
        }
    }

现在更改后保存 xml,如下所示

File.WriteAllText("store.xml",ProductsView.ToList().ToXml());

【讨论】:

  • 非常感谢您的回复,但是当我尝试通过您的代码加载 xml 数据时出现错误。InvalidOperationException: &lt;NewDataSet xmlns=''&gt; was not expected. 我的 xml 文件看起来像:&lt;?xml version="1.0" standalone="yes"?&gt; &lt;NewDataSet&gt; &lt;Product&gt; &lt;ModelName&gt; ....
  • 我给了你xml格式的尝试保存你的xml
  • 我看不出这两个 xml 文件之间的区别
  • NewDataset 不能是 list,如果你序列化 list 你会得到根标签为 ArraOfProduct
  • 我改成和你一样的了,还是报错:InvalidOperationException: &lt;ArraOfProduct xmlns=''&gt; was not expected.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 2011-09-22
  • 2012-03-19
  • 1970-01-01
  • 2012-07-21
相关资源
最近更新 更多