将XML数据加载到WPF DataGrid

时间:2017-05-16 18:05:52

标签: c# xml visual-studio xaml datagrid

在我的WPF应用程序中,应该可以:

读取XML数据并在用户界面中显示它们。

为此,我在MainPage.xaml文件中定义了一个dataGrid:

<DataGrid Name="dataGrid" AutoGenerateColumns="True" />

在代码隐藏文件中,我创建了一个方法来使用xml文件中的数据填充此数据网格:

private void mnuOpen_Click(object sender, RoutedEventArgs e)
{
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
    Nullable<bool> result = dlg.ShowDialog();
    if (result == true)
     {
         string path = System.IO.Path.GetFullPath(dlg.FileName);
         var xml = XDocument.Load(path).Root;
         dataGrid.DataContext = xml;
     }
}

这个编译很好并且运行正常(没有抛出异常) - 但是,xml数据不会显示在UI中。

使用调试器时,有几件奇怪的事情:

  
      
  1. 监视窗口中的变量“path”在整个时间内如下所示:路径错误CS0103:当前上下文中不存在名称“path”

  2.   
  3. 由于某种原因,行

  4.   
var xml = XDocument.Load(path).Root;

似乎“跳了过来”。也就是说,调试器直接来自

string path = System.IO.Path.GetFullPath(dlg.FileName);

dataGrid.DataContext = xml;

我真的不明白这里发生了什么。

1 个答案:

答案 0 :(得分:1)

由于您没有使用XmlDataProvider,因此使用该方法的一个或两个片段来解决问题并省去其余部分并不是很多。 XmlDataProvider很奇怪,涉及它的任何事情都将成为一种解决方法。

在WPF中,您可以通过设置或绑定DataGrid来填充ListBox或任何“集合控件”(ComboBoxItemsSource等)。这是用一个集合填充这些东西的属性。您查看的答案只是一个丑陋的解决方法,可以在ItemsSource被使用时绑定XmlDataProviderDataContext是任何WPF控件都具有的更通用的属性。这是绑定用于查找绑定属性的。你没有约束任何东西,所以稍后再担心。

由于您在代码隐藏中执行此操作,因此速度很快,并且可以使用我在此答案底部包含的示例XML:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
    Nullable<bool> result = dlg.ShowDialog();
    if (result == true)
    {
        string path = System.IO.Path.GetFullPath(dlg.FileName);

        DataSet dataSet = new DataSet();
        dataSet.ReadXml(path);
        DataView dataView = new DataView(dataSet.Tables[0]);
        dataGrid.ItemsSource = dataView;
    }
}

我可能要么从XML创建POCO对象并在viewmodel上的集合中公开它们,要么我非常匆忙,我可能会让viewmodel公开DataView如上所述。但是如果你还没有通过这个项目进入MVVM,你可以将其留给下一个项目。

XML:

<Items>
  <Item Foo="0" Bar="A" />
  <Item Foo="1" Bar="B" />
  <Item Foo="2" Bar="C" />
  <Item Foo="3" Bar="D" />
</Items>

这也有效:

<Items>
  <Item>
    <Foo>0</Foo>
    <Bar>A</Bar>
  </Item>
  <Item>
    <Foo>1</Foo>
    <Bar>B</Bar>
  </Item>
</Items>