Question

After searching and trying several options over the last week, I can't seem to find what I am looking for; maybe someone here can help. While reading through this, please keep in mind that I am attempting to utilize MVVM as strictly as possible, though I am relatively new to WPF. As a side note, I am using Mahapps.Metro to style my window and controls, found here.

I have an XML file that my application uses for configuration (I cannot use the app.config file because the application cannot install on the users' systems). The application will look for this file at start-up and if it does not find the file, it will create it. Below is a snippet of the XML:

<?xml version="1.0" encoding="utf-8"?>
<prefRoot>
  <tabReport>
    <cbCritical>True</cbCritical>
  </tabReport>
</prefRoot>

I reference the XML file in my Window.Resources:

<Controls:MetroWindow.Resources>
        <XmlDataProvider x:Key="XmlConfig"
                         Source="%appdata%\Vulnerator\Vulnerator_Config.xml"
                         XPath="prefRoot"
                         IsAsynchronous="False"
                         IsInitialLoadEnabled="True"/>
</Controls:MetroWindow.Resources>

And utilize this as the DataContext for my MainWindow:

<Controls:MetroWindow DataContext="{DynamicResource XmlConfig}">

Next, I set up a "string-to-bool" converter:

class StringToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            bool? isChecked = (bool?)value;
            return isChecked;
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            string isChecked = value.ToString();
            return isChecked;
        }
        return string.Empty;
    }
}

Finally, I bind IsChecked to the appropriate XPath:

<Checkbox x:Name="cbCritical"
          Content="Critical"
          IsChecked="{Binding XPath=//tabReport/cbCritical, 
                      Converter={StaticResource StringToBool}}" />

After all of this, the applciation loads, but IsChecked is set to false... Any and all ideas would be helpful here; thanks in advance!

Was it helpful?

Solution

I figured out the issue... XAML does not handle % in a file path as expected. To correct, I removed the following from my XAML XmlDataProvider declaration:

Source="%appdata%\Vulnerator\Vulnerator_Config.xml" 
XPath="prefRoot" 

I then set the Source and XPath properties in my code-behind (.xaml.cs):

public MainWindow()
{
    InitializeComponent();

    Uri xmlPath = new Uri (Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Vulnerator\Vulnerator_Config.xml");
    (this.Resources["XmlConfig"] as XmlDataProvider).Source = xmlPath;
    (this.Resources["XmlConfig"] as XmlDataProvider).XPath = "prefRoot";
}

Now, when the application loads, the checkbox is set to the inner value of the XML node specified. Also, I set the Binding Mode=TwoWay to OneTime; two way binding to an XmlDataProvider doesn't occur as expected. To get around this, I am going to bind a command to the Checkbox to update a Dictionary<string, string> (created at startup in my view-model constructer) with the new IsChecked value. I will use the Dictionary to control what the application does based off of user input, and write the new Dictionary user values to the XML file once the application is closed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top