我已经寻找并尝试了各种解决方案,但到目前为止,它们都没有解决我的问题。我在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。我会尝试一些建议,看看我能开展什么工作。
答案 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;