2010-02-04 1 views
7

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

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

ответ

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> 
+0

В результате возникает сообщение InvalidOperationException с сообщением: «Элемент коллекции должен быть пуст перед использованием ItemsSource.Это происходит при выполнении назначения DataContext или в обработчике событий для PropertyChanged, поэтому предотвращает либо реализацию. Редактировать: Нет, t, я забыл добавить вокруг моих определений столбцов. – IanGilham

+0

Исключение было моей ошибкой. Это прекрасно работает. – IanGilham

+0

О, человек, отладка xaml может быть неприятной. – Natxo

1

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

XPath не работает с классами XDocument. Единственный способ привязки к свойствам XDocument - это обычный синтаксис пути, который не поддерживается 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; 
+0

Но как бы вы загружаете весь XML-документ для редактирования в DataGrid. Я имею в виду, как вы сопоставляете определенные элементы XML и их атрибуты с столбцами DataGrid и редактируете только те из них? –