如何正确地将xml绑定到WPF DataGrid?

时间:2010-02-04 12:47:43

标签: wpf data-binding wpfdatagrid

我已经寻找并尝试了各种解决方案,但到目前为止,它们都没有解决我的问题。我在Visual Studio 2010 / .NET4中使用WPF内置的DataGrid来显示存储为XDocument的XML文档中的数据。

我的代码运行良好,我已经验证XDocument存在且正确。但是,DataGrid不显示任何数据。

XML看起来像这样(为简洁起见而简化):

<data>
  <track>
    <id>211</id>
    <name>Track Name</name>
    <duration>156</duration>
    <artist_id>13</artist_id>
    <artist_name>Artist Name</artist_name>
    <album_id>29</album_id>
    <album_name>Album Name</album_name>
  </track>
...
</data>

我的XAML看起来像这样:

<DataGrid x:Name="LibraryView" Grid.Row="1"
              DataContext="{Binding Path=TrackList}" ItemsSource="{Binding XPath=/data/track}">
    <DataGridTextColumn Header="Title" Binding="{Binding XPath=name}"/>
    <DataGridTextColumn Header="Artist" Binding="{Binding XPath=artist_name}"/>
    <DataGridTextColumn Header="Album" Binding="{Binding XPath=album_name}"/>
    <DataGridTextColumn Header="Length" Binding="{Binding XPath=duration}"/>
</DataGrid>

备份它的C#只是将新的XDocument(从Web服务下载)分配给TrackList属性(实现INotifyPropertyChanged)。没有进一步处理。

我以前曾尝试使用XLinq,绑定到查询结果,这也不起作用(同样的问题),所以我想我会尝试使用XPath方法来避免编写可能有bug的Linq语句,并尝试找到问题。

对于如何正确显示DataGrid,我的想法已经不多了。我对这应该如何工作的理解显然是缺乏的,所以我非常感谢你提供的任何帮助。

编辑:值得注意的是,我对输入数据格式有一定的灵活性,因为我自己正在下载原始XML。我会尝试一些建议,看看我能开展什么工作。

2 个答案:

答案 0 :(得分:9)

我使用XLinq并且工作正常,使用XElement而不是XDocument:

XElement TrackList = XElement.Load("List.xml");
LibraryView.DataContext = TrackList;

的Xaml:

<DataGrid x:Name="LibraryView" ItemsSource="{Binding Path=Elements[track]}">
    <DataGrid.Columns>
         <DataGridTextColumn Header="Artist" Binding="{Binding Path=Element[artist_name].Value}"/>
         <DataGridTextColumn Header="Album" Binding="{Binding Path=Element[album_name].Value}"/>
         <DataGridTextColumn Header="Length" Binding="{Binding Path=Element[duration].Value}"/>
    </DataGrid.Columns>
</DataGrid>

答案 1 :(得分:1)

绑定XPath仅在绑定到XmlNode的某些内容时才有意义(例如,您使用的是XmlDataProvider)。请参阅here

XPath不适用于XDocument类。绑定到XDocument属性的唯一方法是普通的Path语法,它不支持XML。

最好的办法是使用XmlDataSource,或者通过XDocument将Xml文档转换为POCO。使用LINQ非常简单:

XDocument doc = XDocument.Load(xmlFile);

            var tracks = from track in doc.Descendants("data") 
                    select new Track()
                               {
                                   Name= track.Element("name").Value,    
                                   Duration= track.Element("duration").Value,    
                                   etc ... 
                               };
LibraryView.ItemsSource = tracks;