WPF : Binding to global App properties

I was working on something for an upcoming article that I am writing where I am messing around with 3D, and I was having a small issue with a VisualBrush (something to do with Freezable, I never did quite figure it out and came up with a better solution), but along the way of trying to figure that out, one of the ideas I had was to use a globally available Application property and Bind to that. This is something I had not done before. Luckily it is very simple.

The only thing that you have to be aware of is that you can not use the normal DP GetValue() SetValue() syntax in Application inheriting objects, as these are added further up the inheritance tree (DependencyObject) where as Application inherits from DispatcherObject, so does not have these methods.

So we must simply use CLR properties.

Here is a small example.

My App class looks like this

   1:  public partial class App : Application
   2:  {
   3:      private String someText="default";
   4:  
   5:      public String SomeText
   6:      {
   7:          get { return this.someText; }
   8:          set { this.someText = value; }
   9:      }
  10:  }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }And I have a small XAML Window which wants to bind to one of the App properties, we simply use the following Binding, note the x:Static markup extension.

   1:  <Window x:Class="BindingToApp.Window1"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      Title="Window1" Height="300" Width="300">
   5:  
   6:      <StackPanel Orientation="Vertical">
   7:          <TextBlock Margin="5" TextWrapping="Wrap"
   8:                     Text="Shows how to bind to App level properties, 
   9:                     type below and then click button"/>
  10:          <TextBox x:Name="txt" Margin="5" >
  11:              <TextBox.Text>
  12:                  <Binding Path="SomeText"
  13:                           Source="{x:Static Application.Current}"/>
  14:              </TextBox.Text>
  15:          </TextBox>
  16:          <Button x:Name="BtnShowAppSetting" Margin="5"
  17:                  Content="What is App Value Now"
  18:                  Click="BtnShowAppSetting_Click"/>
  19:      </StackPanel>
  20:  
  21:  </Window>

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }And here is the code behind

   1:      public partial class Window1 : Window
   2:      {
   3:          public Window1()
   4:          {
   5:              InitializeComponent();
   6:          }
   7:  
   8:          private void BtnShowAppSetting_Click(object sender, RoutedEventArgs e)
   9:          {
  10:              MessageBox.Show(String.Format("App value for SomeText property is {0}",
  11:                  (Application.Current as App).SomeText));
  12:          }
  13:      }

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }And here is the result when run

props

Here is a link to this demo project in case you need to try it : bindingtoapp.zip

Along the way I also found a very interesting post that illustrated how to bind directly to the Settings files that can be added to a VS project. That is pretty useful for persisting user specific data. Here is a link to that article

http://dedjo.blogspot.com/2008/04/quick-wpf-tip-how-to-bind-to-wpf.html

Enjoy

About these ads

16 thoughts on “WPF : Binding to global App properties

  1. Raul Mainardi Neto says:

    Nice one again Sacha, but that one i already knew… looking forward for your article… cant wait until release.. every time you promisse something nice you come up with something like the fun with physics article… and lets be fair to your affort… you should be paid for something that good.

    All best mate…

    Raul

  2. Alex S-D says:

    Can you move the public property to its own public class and make a call to it still?

    I’m thinking about making the code tidy ??

    e.g. Public Class myProperties
    {
    private String someText=”default”;
    public String SomeText
    { get { return this.someText; }
    set { this.someText = value; }
    }
    }

    public partial class App : Application
    {
    public static myProperties myProps = new myProperties();

    }

    The Binding Path now no longer works?

  3. Alex S-D says:

    :-) Never mind, worked it out…

    public partial class App : Application
    {
    private static myProperties myProps = new myProperties();

    public static myProperties MyProps
    {
    get { return myProps; }
    }

    }

  4. sacha says:

    Alex this should work. You can bind anything to anything providing the DataContext has that property. And of course the Binding fails in your example, as its still pointing to {x:Static Application.Current} So you would need to do something like

    <Binding Path=”myProps.SomeText”
    Source=”{x:Static Application.Current}”/>

    • sacha says:

      Assuming you App class is called “MyApp” and your property you want value is called “MyProp” you would do something like

      var x = ((MyApp)Application.Current).MyProp;

  5. hermann says:

    Since Application contains a Properties dictionary, that would be a good place for me to put all contextual data into, using

    App.Current.Properties[“MyDataContext”] = myobject;

    Is it possible to bind via xaml to such a “MyDataContext” as well?

    • sacha says:

      Yeah I am not sure you could bind to the properties property directly, as its a dictionary. Perhaps by using a ValueConverter you could.

      Your Value converter could take a Key as the value and get it from App.Current

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s