Search code examples
c#xmlwpfbindingcode-behind

How to bind WPF Checkbox to XML element value using code behind (C#)?


I have an XML document like this:

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <Variable>
    <IsChecked>False</IsChecked>
    <ID>A</ID>
    <Description></Description>
  </Variable>
  <Variable>
    <IsChecked>True</IsChecked>
    <ID>B</ID>
    <Description></Description>
  </Variable>
  <Variable>
    <IsChecked>False</IsChecked>
    <ID>C</ID>
    <Description></Description>
  </Variable>
</Root>

I want to create a Grid where the first column includes checkboxes. Each row should have a checkbox two-way-binded to each variable. I think my mistake is in the Source and/or XPath.

XAML:

<Grid x:Name="ValuesGrid" >
    <Grid.Resources>
         <XmlDataProvider x:Key="VarValuesData" Source="Resources\VariablesValues.xml" XPath="Root"/>
    </Grid.Resources>
</Grid>

Code behind:

//Add the checkboxes
for (int i = 0; i < 26; i++) 
{
    Binding binding = new Binding(); 
    binding.Mode = BindingMode.TwoWay;
    binding.NotifyOnSourceUpdated = true;

    binding.Source = "{StaticResource VarValuesData}";
    int position = 1 + i;
    binding.XPath = "Root/Variable[" + position + "]/IsChecked";

    CheckBox cbTemplate = new CheckBox();
    cbTemplate.SetBinding(CheckBox.IsCheckedProperty, binding);//Here I get the exception.
    Grid.SetRow(cbTemplate, 1+i);
    Grid.SetColumn(cbTemplate, 0);

    ValuesGrid.Children.Add(cbTemplate);
}

When I try this code I get the following error message (traduction): "The entry string doesn't have the correct format".


Solution

  • There are a few things wrong:

    • You need to get a reference to the XmlDataProvider from the Resources of the Grid in order to use it as Binding Source.
    • The XPath must not (again) contain Root.
    • Grid.Row index starts at 0

    The following reads the XML data correctly. Not sure however about TwoWay, i.e. saving back to the XML file.

    var dataProvider = (XmlDataProvider)ValuesGrid.Resources["VarValuesData"];
    
    for (int i = 0; i < 3; i++)
    {
        int position = 1 + i;
    
        var binding = new Binding
        {
            Source = dataProvider,
            XPath = "Variable[" + position + "]/IsChecked",
            Mode = BindingMode.TwoWay
        };
    
        var checkBox = new CheckBox();
        checkBox.SetBinding(CheckBox.IsCheckedProperty, binding);
        Grid.SetRow(checkBox, i);
    
        ValuesGrid.Children.Add(checkBox);
    }