Search code examples
wpfdata-bindingwpfdatagrid

How to bind xml to the WPF DataGrid correctly?


I have looked for and tried various solutions but so far none of them solve my problem. I am using the built-in DataGrid from WPF in Visual Studio 2010/.NET4 to display data from an XML document stored as an XDocument.

My code all runs fine, and I have verified that the XDocument is present and correct. The DataGrid does not display any data, however.

The XML looks like this (simplified for clarity):

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

My XAML looks like this:

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

The C# that backs it up just assigns a new XDocument (downloaded from a web service) to the TrackList property (which implements INotifyPropertyChanged). No further processing is done on it.

I have previously tried using XLinq, to bind to a query result, which didn't work either (same problem), so I thought I'd try the XPath approach to avoid writing a potentially buggy Linq statement, and try to find the problem.

I am running out of ideas for how to get the DataGrid to display correctly. My understanding of how this is supposed to work is clearly lacking, so I would greatly appreciate any help offered.

Edit: It is worth noting that I have some flexibility with the input data format, as I am downloading raw XML myself. I will try some of the suggestions and see what I can get to work.


Solution

  • I used XLinq and worked fine, using a XElement instead of a 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>