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

Viewed 36510

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?

7 Answers

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); 
}

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.

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.

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!

Related