Best way to bind WPF properties to ApplicationSettings in C#?

C#.NetWpfVisual Studio

C# Problem Overview


What is the best way to bind WPF properties to ApplicationSettings in C#? Is there an automatic way like in a Windows Forms Application? Similar to this question, how (and is it possible to) do you do the same thing in WPF?

C# Solutions


Solution 1 - C#

You can directly bind to the static object created by Visual Studio.

In your windows declaration add:

xmlns:p="clr-namespace:UserSettings.Properties"

where UserSettings is the application namespace.

Then you can add a binding to the correct setting:

<TextBlock Height="{Binding Source={x:Static p:Settings.Default}, 
           Path=Height, Mode=TwoWay}" ....... />

Now you can save the settings, per example when you close your application:

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    Properties.Settings.Default.Save();
    base.OnClosing(e); 
}

Solution 2 - C#

In case you are a VB.Net developer attempting this, the answer is a smidge different.

xmlns:p="clr-namespace:ThisApplication"

Notice the .Properties isn't there.


In your binding it's MySettings.Default, instead of Settings.Default - since the app.config stores it differently.

<TextBlock Height={Binding Source={x:Static p:MySettings.Default}, Path=Height, ...

After a bit of pulling out my hair, I discovered this. Hope it helps

Solution 3 - C#

I like the accepted answer, I ran into a special case though. I had my text box set as "read only" so that I can change the value of it only in the code. I couldn't understand why the value wasn't propagated back to the Settings although I had the Mode as "TwoWay".

Then, I found this: http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx

> The default is Default, which returns the default UpdateSourceTrigger value of the target dependency property. However, the default value for most dependency properties is PropertyChanged, while the Text property has a default value of LostFocus.

Thus, if you have the text box with IsReadOnly="True" property, you have to add a UpdateSourceTrigger=PropertyChanged value to the Binding statement:

<TextBox Text={Binding Source={x:Static p:Settings.Default}, Path=myTextSetting, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} ... />

Solution 4 - C#

The easiest way would be to bind to an object that exposes your application settings as properties or to include that object as a StaticResource and bind to that.

Another direction you could take is creation your own Markup Extension so you can simply use PropertyName="{ApplicationSetting SomeSettingName}". To create a custom markup extension you need to inherit MarkupExtension and decorate the class with a MarkupExtensionReturnType attribute. John Bowen has a post on creating a custom MarkupExtension that might make the process a little clearer.

Solution 5 - C#

Kris, I'm not sure this is the best way to bind ApplicationSettings, but this is how I did it in Witty.

  1. Create a dependency property for the setting that you want to bind in the window/page/usercontrol/container. This is case I have an user setting to play sounds.

     public bool PlaySounds
     {
         get { return (bool)GetValue(PlaySoundsProperty); }
         set { SetValue(PlaySoundsProperty, value); }
     }
    
     public static readonly DependencyProperty PlaySoundsProperty =
         DependencyProperty.Register("PlaySounds", typeof(bool), typeof(Options),
         new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnPlaySoundsChanged)));
    
     private static void OnPlaySoundsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
     {
         Properties.Settings.Default.PlaySounds = (bool)args.NewValue;
         Properties.Settings.Default.Save();
     }
    
  2. In the constructor, initialize the property value to match the application settings

       PlaySounds = Properties.Settings.Default.PlaySounds;
    
  3. Bind the property in XAML

       <CheckBox Content="Play Sounds on new Tweets" x:Name="PlaySoundsCheckBox" IsChecked="{Binding Path=PlaySounds, ElementName=Window, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    

You can download the full Witty source to see it in action or browse just the code for options window.

Solution 6 - C#

I like to do it through the ViewModel and just do the binding as normal in the XAML

    public Boolean Value
    {
        get
        {
            return Settings.Default.Value;
           
        }
        set
        {
            Settings.Default.SomeValue= value;
            Settings.Default.Save();
            Notify("SomeValue");
        }
    }

Solution 7 - C#

Also read this article on how it is done in BabySmash

You only need to back the Settings with DO (Like Alan's example) if you need the change notification! binding to the POCO Settings class will also work!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKris EricksonView Question on Stackoverflow
Solution 1 - C#Sacha BruttinView Answer on Stackoverflow
Solution 2 - C#TknoSpzView Answer on Stackoverflow
Solution 3 - C#RemusView Answer on Stackoverflow
Solution 4 - C#Richard SzalayView Answer on Stackoverflow
Solution 5 - C#Alan LeView Answer on Stackoverflow
Solution 6 - C#NathofGodView Answer on Stackoverflow
Solution 7 - C#rudigroblerView Answer on Stackoverflow