Как правильно связать XML с WPF DataGrid? - PullRequest
7 голосов
/ 04 февраля 2010

Я искал и пробовал различные решения, но пока ни одно из них не решило мою проблему. Я использую встроенную DataGrid из WPF в Visual Studio 2010 / .NET4 для отображения данных из документа XML, хранящегося в виде XDocument.

Мой код работает нормально, и я убедился, что 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 (загруженный из веб-службы) свойству TrackList (которое реализует INotifyPropertyChanged). Дальнейшая обработка на нем не производится.

Ранее я пытался использовать XLinq для привязки к результату запроса, который тоже не работал (та же проблема), поэтому я решил попробовать подход XPath, чтобы избежать написания потенциально ошибочного оператора Linq, и попытаться найти проблему.

У меня заканчиваются идеи о том, как заставить DataGrid отображаться правильно. Мое понимание того, как это должно работать, явно отсутствует, поэтому я был бы очень признателен за любую предложенную помощь.

Редактировать: Стоит отметить, что у меня есть некоторая гибкость с форматом входных данных, так как я сам загружаю необработанный XML. Я попробую некоторые из предложений и посмотрю, что я получу на работе.

Ответы [ 2 ]

9 голосов
/ 05 февраля 2010

Я использовал 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 голос
/ 05 февраля 2010

Привязка XPath имеет значение, только если вы привязываетесь к чему-то, что является XmlNode (например, вы используете XmlDataProvider).См. здесь .

XPath не работает с классами XDocument.Единственный способ привязки к свойствам XDocument - это обычный синтаксис Path, который не поддерживает XML.

Лучше всего либо использовать XmlDataSource, либо преобразовать документ Xml через XDocument в 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;
...