Tuesday, April 22, 2008

Quick WPF Tip: How to bind to WPF application resources and settings?

You, probable know, that you can save application resources and settings within handy classes Settings and Properties, provided by Visual Studio code generator. Just put your values, set the usage scope and all you have to do is to save it upon request.

image

This feature is really useful and great time saver. But how to use it from WPF? Visual Studio do not know to create Dependency Objects for setting and resource… Following the sample of how designer saves setting information

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
   internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
       private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
       public static Settings Default {
           get {
               return defaultInstance;
           }
       }
       [global::System.Configuration.UserScopedSettingAttribute()]
       [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
       [global::System.Configuration.DefaultSettingValueAttribute("0")]
       public double Left {
           get {
               return ((double)(this["Left"]));
           }
           set {
               this["Left"] = value;
           }
       }

As you can see it creates singleton and publish relevant properties through it, thus you can access the information by using following syntax

UserSettings.Properties.Settings.Default.Left = 10;

But how to create binding for such structure? Simple – this is regular static class. As well as DateTime.Now and so. Also we are not interested to know, whenever this property updated. This means, that following code will do all necessary work.

<Window x:Class="UserSettings.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:p="clr-namespace:UserSettings.Properties"
    WindowStartupLocation="Manual"
    Title="Window1"
    Height="{Binding Source={x:Static p:Settings.Default}, Path=Height, Mode=TwoWay}"
    Width="{Binding Source={x:Static p:Settings.Default}, Path=Width, Mode=TwoWay}"
    Left="{Binding Source={x:Static p:Settings.Default}, Path=Left, Mode=TwoWay}"
    Top="{Binding Source={x:Static p:Settings.Default}, Path=Top, Mode=TwoWay}"

As you see, we just point by using x:Static provider of type UserSettings.Properties.Settings.Default and requesting it’s members. Now all you have to do is to save updated information upon the application exit.

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

We done. Starting now, user can move and resize WPF window and all information will be saved in Settings class automatically. Next time this user will open the application it will restore it state (position and size) automatically.

Happy coding.

1 comment:

Jani said...

Hi Tamir

Well Done!

I have developed another generic approach to bind a setting to a dependency property.

http://www.codeproject.com/KB/dotnet/user_settings.aspx

Regards,
Jani