简体   繁体   English

如何在WPF应用程序中将DataGrid导出到XML?

[英]How can I export a DataGrid to XML in WPF application?

I have a DataGrid called GokartDataGrid. 我有一个名为GokartDataGrid的DataGrid It has some columns and rows, and I would like to export the table into an XML file, but the method I found giving an exception for me. 它具有一些列和行,我想将表导出到XML文件中,但是我发现该方法给了我一个例外。 My code is looks like this, and it says System.InvalidCastException at the DataTable instantiation. 我的代码如下所示,它在DataTable实例化时显示System.InvalidCastException

private void Xml_export() 
{
    DataTable dt = (DataTable)GokartDataGrid.ItemsSource;
    SaveFileDialog savefile = new SaveFileDialog();
    savefile.Filter = "XML |*.xml";
    savefile.ShowDialog();
    savefile.CheckFileExists = true;
    savefile.CheckPathExists = true;
    dt.WriteXml(savefile.FileName);         
}

I will make a try-catch section after it works, but right now I don't know what can I do. 在工作之后,我将创建一个try-catch部分,但是现在我不知道该怎么办。
What should I do to make it work? 我应该怎么做才能使其正常工作? Okay so here is the upload of the datagrid. 好的,这是datagrid的上传。

    public void DataGridUpload(string filepath)
    {
        if (filepath != null) 
        { 
        Gokart_container minden = new Gokart_container(filepath);
        GokartDataGrid.ItemsSource = minden.GetGokartlist();
        }
    }

The Gokart_container contains Gokart objects in a list and the Gokart object has a few datas in it like best lap time and all laps in an other list. Gokart_container在一个列表中包含Gokart对象,并且Gokart对象在其中包含一些数据,例如最佳圈速和其他圈中的所有圈。 And some strings like racer name. 还有一些字符串,例如赛车手的名字。

The datagrid.Columns can give you the column header order. datagrid.Columns可以为您提供列标题顺序。 And the datagrid.Items.SourceCollection the row values. 和datagrid.Items.SourceCollection行值。 And you go from there. 然后你从那里去。

I don't know for sure what it is, but that error is saying you don't have a datatable as an itemssource. 我不确定这是什么,但是该错误表示您没有数据表作为itemssource。
Which is doubly true. 这是双重事实。

Your ItemsSource cannot be a datatable. 您的ItemsSource不能是数据表。
If I try setting the itemssource of a datagrid to one I get the error: 如果我尝试将数据网格的itemssource设置为1,则会收到错误消息:

Cannot implicitly convert type 'System.Data.DataTable' to 'System.Collections.IEnumerable'. 无法将类型'System.Data.DataTable'隐式转换为'System.Collections.IEnumerable'。 An explicit conversion exists (are you missing a cast?) 存在显式转换(您是否缺少演员表?)

So I don't know what GetGokartlist() returns, but it isn't a datatable. 所以我不知道GetGokartlist()返回什么,但这不是数据表。 You could possibly be using the defaultview of a datatable. 您可能正在使用数据表的默认视图。 Because this works: 因为这有效:

dg.ItemsSource = dt.DefaultView;

If I then do a gettype to check what that is: 如果我然后执行gettype检查是什么:

Type isType = dg.ItemsSource.GetType();

It's a DataView rather than a datatable. 它是一个DataView而不是一个数据表。

Maybe you could cast to dataview and work with that. 也许您可以转换为dataview并使用它。 But maybe that's not what you have anyhow. 但这也许不是您所拥有的。

But you say Gokart objects in a List. 但是你说Gokart在一个List对象。
Which sounds like a List. 听起来像一个列表。
So you could possibly cast to List 这样您就可以投放到列表

But casting some data you get back out the front end when you gave the datagrid that data in the first place is an unusual way to work. 但是,当您向datagrid证明数据首先是一种不寻常的工作方式时,投射一些数据会从前端返回。

It's more usual to work with wpf using MVVM. 使用MVVM使用wpf更为常见。
Like this: 像这样:
https://social.technet.microsoft.com/wiki/contents/articles/32164.wpf-mvvm-step-by-step-2.aspx https://social.technet.microsoft.com/wiki/contents/articles/32164.wpf-mvvm-step-by-step-2.aspx

With MVVM you'd have a viewmodel which retains a reference to the collection of GoKart. 使用MVVM,您将拥有一个视图模型,该模型保留了对GoKart集合的引用。 This would usually be an observablecollection rather than a List. 这通常是一个可观察的集合,而不是一个List。 An observablecollection raises collection changed when you add or remove an item which is useful AND the datagrid loses some functionality if you bind to a List. 当您添加或删除有用的项目时,observablecollection会引发更改集合,并且如果您绑定到List,则数据网格将失去某些功能。

Anyhow, this way you'd have a reference to the collection of data and can work with that directly. 无论如何,通过这种方式,您可以引用数据收集并直接使用它。
How about xml from a List ? 列表中的xml怎么样?
Often it's not just the one property you want to serialise, there's a whole load of them. 通常,不仅仅是要序列化的一个属性,还有它们的全部负载。
You could create a class which has one property, a List and fill that from your observablecollection using Linq and .ToList(). 您可以创建一个具有一个属性(列表)的类,并使用Linq和.ToList()从您的observablecollection中填充该属性。
You then just serialise that class and you have all your data as xml. 然后,您只需序列化该类,然后将所有数据作为xml。
Just make your class public, the properties public and use datacontractserialiser. 只需公开您的课程,属性公开并使用datacontractserialiser。

Here's an example bit of code which serialises to disk and deserialises back: 这是一些示例代码,可序列化到磁盘并反序列化:

    public static void SaveScenario(string fileURL, Scenario scenario)
    {
        scenario.ScenarioFile = fileURL;
        using (FileStream writer = new FileStream(fileURL, FileMode.Create))
        {
            DataContractSerializer ser = new DataContractSerializer(typeof(Scenario));
            ser.WriteObject(writer, scenario);
        } 
    }
    public static Scenario ReadScenario(string fileURL)
    {
        FileStream fs = new FileStream(fileURL, FileMode.Open);
        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
        DataContractSerializer ser = new DataContractSerializer(typeof(Scenario));
        Scenario deserializedScenario = (Scenario)ser.ReadObject(reader, true);
        reader.Close();
        fs.Close();
        return deserializedScenario;
    }
}   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM