2010-02-04 17 views
7

He buscado y probado varias soluciones, pero hasta ahora ninguna solucionó mi problema. Estoy usando el DataGrid integrado de WPF en Visual Studio 2010/.NET4 para mostrar datos de un documento XML almacenado como XDocument.¿Cómo vincular correctamente xml al WPF DataGrid?

Mi código funciona bien, y he verificado que el XDocument está presente y es correcto. Sin embargo, DataGrid no muestra ningún dato.

El XML es similar a esto (simplificado para mayor claridad):

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

Mi XAML se parece a esto:

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

El C# que lo respalda simplemente asigna un nuevo XDocument (descargado desde una servicio web) a la propiedad TrackList (que implementa INotifyPropertyChanged). No se realiza ningún procesamiento adicional en él.

He intentado anteriormente utilizar XLinq, para enlazar a un resultado de la consulta, que tampoco funcionó (mismo problema), así que pensé en probar el enfoque XPath para evitar escribir una declaración Linq potencialmente errónea, y probar para encontrar el problema

Me estoy quedando sin ideas sobre cómo hacer que DataGrid se muestre correctamente. Mi comprensión de cómo se supone que funciona esto es claramente deficiente, por lo que agradecería mucho cualquier ayuda ofrecida.

Editar: Vale la pena señalar que tengo cierta flexibilidad con el formato de datos de entrada, ya que estoy descargando XML sin procesar. Voy a probar algunas de las sugerencias y ver a qué puedo llegar para trabajar.

Respuesta

9

Solía ​​XLinq y funcionó bien, usando un XElement en lugar de un 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

Esto genera una InvalidOperationException con el mensaje "La colección de elementos debe estar vacía antes de usar ItemsSource. Esto ocurre al realizar la asignación a DataContext, o en el controlador de evento para PropertyChanged, por lo que evita cualquier implementación. Editar: No it does ' t, me olvidé de agregar alrededor de las definiciones de mi columna. – IanGilham

+0

La excepción fue mi error. Esto funciona bien. – IanGilham

+0

Oh, hombre, depurar xaml puede ser desagradable. – Natxo

1

Encuadernación XPath solo es relevante si está vinculando a algo que es un XmlNode (por ejemplo, está utilizando XmlDataProvider). Ver here.

XPath no funciona con clases XDocument. La única forma de vincularse a las propiedades de un XDocument es la sintaxis de ruta normal, que no es compatible con XML.

Su mejor opción es utilizar XmlDataSource o convertir su documento Xml a través de XDocument en un POCO. Eso es bastante simple usando 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

Pero ¿cómo cargar una todo el documento XML para editar en un DataGrid. Quiero decir, ¿cómo mapear ciertos elementos XML y sus atributos a las columnas de DataGrid y editar solo esos? –