WPF Code Behind: DataGridTextColumn shows Column headers but not data from xmlprovider with xpath

StackOverflow https://stackoverflow.com/questions/22631537

  •  20-06-2023
  •  | 
  •  

Question

I'm trying to show data from XMLProvider with XPath. Because of the the dynamic nature of the xml file I need to load the data via code behind.

I'm looking for a datagrid looking like this:

Sensor    BIS  MAN  BIS  MAN
-----------------------------
Sensor1   45   43   44   46
Sensor2   45   43   43   45

FYI: above the grid I'll be showing a fake super header to group BIS & MAN values (in case you don't understand why BIS & MAN keywords are repeating)

XAML code for the datagrid:

<DataGrid Name="MDataGrid" AutoGenerateColumns="False"></DataGrid>

This is the XML file sample data:

<?xml version="1.0" encoding="utf-8" ?>
<ShipData>
  <Draught>
    <Measures>
      <Mdata>M1</Mdata>
      <Mdata>M2</Mdata>
    </Measures>
    <Sensor Name="Sensor1">
      <Measurement>
        <Bis>45</Bis>
        <Man>43</Man>
      </Measurement>
      <Measurement>
        <Bis>44</Bis>
        <Man>46</Man>
      </Measurement>
    </Sensor>
    <Sensor Name="Sensor2">
      <Measurement>
        <Bis>45</Bis>
        <Man>43</Man>
      </Measurement>
      <Measurement>
        <Bis>43</Bis>
        <Man>45</Man>
      </Measurement>
    </Sensor>
  </Draught>
</ShipData>

And here is the code behind c# code I'm using:

// loading xml for grid
XmlDocument doc = new XmlDocument();
doc.Load(_file_location_); // (it does find the xml)

// setting the xml provider
XmlDataProvider _xmlDataProvider = new XmlDataProvider();
_xmlDataProvider.Document = doc;
_xmlDataProvider.XPath = @"/ShipData/Draught/Sensor";

// Setting the datacontext for 
MDataGrid.DataContext = _xmlDataProvider; 

// Creating the column Sensor (as an example) and create a new binding for xpath
var dataGridTextColumn = new DataGridTextColumn();

Binding bindingSensor = new Binding();
bindingSensor.Source = _xmlDataProvider;
bindingSensor.XPath = "@Name";
dataGridTextColumn.Binding = bindingSensor;

dataGridTextColumn.Header = "Sensor";

// other repeating columns (bis+man ...) omitted for this example

// adding the column to the datagrid
MDataGrid.Columns.Add(dataGridTextColumn);

The header for the sensor column is showing, but there's no data listed in the grid. Where am I wrong?

Was it helpful?

Solution 2

Apparently you need an extra Binding as someone else pointed me out. I don't know why exactly, but it does the job perfectly.

// loading xml for grid
XmlDocument doc = new XmlDocument();
doc.Load(_file_location_); // (it does find the xml)

// setting the xml provider
XmlDataProvider _xmlDataProvider = new XmlDataProvider();
_xmlDataProvider.Document = doc;
_xmlDataProvider.XPath = @"/ShipData/Draught/Sensor";

// Setting the datacontext (updated code)
Binding binding = new Binding();
binding.Source = _xmlDataProvider;
MDataGrid.SetBinding(DataGrid.ItemsSourceProperty, binding);

// Creating the column Sensor (as an example) and create a new binding for xpath
var dataGridTextColumn = new DataGridTextColumn();

Binding bindingSensor = new Binding();
bindingSensor.XPath = "@Name";
dataGridTextColumn.Binding = bindingSensor;

dataGridTextColumn.Header = "Sensor";

// other repeating columns (bis+man ...) omitted for this example

// adding the column to the datagrid
MDataGrid.Columns.Add(dataGridTextColumn);

It does also work for the added columns I wanted (using dynamically adjusted XPath code)

Credit goes to: Magnus (MM8)

OTHER TIPS

That isn't extra as you state in answer. That is indeed required step. DataGrid display data supplied to ItemsSource property, so there won't be any data displayed if you didn't set ItemsSource. Instead of manually setting ItemsSource binding in code, you can do it in XAML :

<DataGrid Name="MDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False">

and set DataContext from code-behind as you already did :

......
// Setting the datacontext for 
MDataGrid.DataContext = _xmlDataProvider; 
......
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top