1

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

Alce
  • 23
  • 6
  • well, 10+ years wpf development experience, first time seeing someone using xPath in Binding. – Rand Random Jun 28 '23 at 09:50
  • okay... I am blind... `binding.Source = "{StaticResource VarValuesData}";` <--- that not how you do a staticresource in code behind, the string wont be parsed as you may believe - just do `binding.Source = VarValuesData;` – Rand Random Jun 28 '23 at 10:03
  • Thank you Rand Random. So, it's not a good idea to use XPath? To put directly VarValuesData gives an error. – Alce Jun 28 '23 at 10:23
  • 1
    Since you asked `So, it's not a good idea to use XPath?` I would deserialize the xml to a c# class and use normal binding, and upon save I would serialize the class back to xml. have a look at: https://stackoverflow.com/questions/364253/how-to-deserialize-xml-document | https://stackoverflow.com/questions/4123590/serialize-an-object-to-xml – Rand Random Jun 28 '23 at 14:01

1 Answers1

1

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);
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Thank you. Now I don't get the error. I will read about the syntax of Resources and how the XmlDataProvider works. Unfortunatelly, the checkboxes don't get checked. – Alce Jun 28 '23 at 10:33
  • They get checked for me with your sample data. Make sure the XML file is copied to the output directory by setting its *Build Action* to *Content* and *Copy to Output Directory* to a value other than *Do not Copy*. – Clemens Jun 28 '23 at 10:37
  • It is set to "Copy if newer". – Alce Jun 28 '23 at 12:15
  • If I create a new solution, it works fine (not two-way). I don't know why the original solution doesn't get the checks. Should be something about the location of the file. – Alce Jun 28 '23 at 13:04
  • Maybe [this](https://stackoverflow.com/a/66193276/1136211) helps with saving the data. Note that the file in the Output Directory is typically read-only. – Clemens Jun 28 '23 at 13:24
  • Yes, sure. Thanks again Clemens. I was waiting to solve the problem 100%. – Alce Jun 29 '23 at 10:13