Winsmarts.com

Microsoft MVP

MVP Logo

Awarded the Microsoft MVP Award.

Hosted By

blah!bLaH!BLOG!!

WPF: Dependency Properties

.. when one property of one class depends on the other class property.

Posted on 2/13/2007 @ 4:18 PM in #WPF | 0 comments | 5437 views

So you already know that XAML is HTML-esque. In other words, it tries to adopt the XML declarative style, or markup style in helping the programmer express his intent - atleast as far as the UI is concerned. This has numerous advantages, but I won't go into those now. But I invite you to look a tad bit deeper into this HTML'sque XML declarative way of specifying thick client UIs.

Examine the following XAML -

<Window x:Class="SayHello.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Winsmarts.com">
    <StackPanel Margin="20">
      <TextBlock>My Blog is http://blah.winsmarts.com</TextBlock>
    </StackPanel>
</Window>


Seems pretty straightforward eh? This is absolutely the same as expressing the above intent, in the following code -

public partial class Window1 : System.Windows.Window
{
    public Window1()
    {
        StackPanel panel = new StackPanel();
        panel.Margin = new Thickness(20);
        Content = panel;

        TextBlock txt = new TextBlock();
        txt.Inlines.Add("My Blog is http://blah.winsmarts.com");
    }
}

As you can see, the "HTML'sque" XAML translates to setting various properties. So the following XAML -

<StackPanel Margin="20">
  <TextBlock FontSize="20">My Blog is http://blah.winsmarts.com</TextBlock>
</StackPanel>

... should translate to the one extra line of code that looks like this - txt.FontSize = 20; ?

Ummmm .. well, go ahead and type that up in Visual Studio. You should see a window that looks like this -

Pretty much what you expected huh? Now this is where it starts getting funky.

Now change your XAML to look like this -

<Window x:Class="SayHello.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Winsmarts.com" FontSize="20"
    >
  <StackPanel Margin="20">
    <TextBlock>My Blog is http://blah.winsmarts.com</TextBlock>
    </StackPanel>
</Window>

The only change I made is, I moved "FontSize=20" to Window. Now if you run the program, the output looks like this -

**** What the heck?

This makes complete sense from an HTML perspective - setting font on <body> means the entire document seems to inherit the font. But if you translate this in C#, I gotta ask, who the heck is setting this property on TextBlock? I know the clever ones of you think that the sneaky MSFT programmers do some magic behind the scenes, and the recursively look at all child controls and set the necessary property eh?

But if that was true ..  then StackPanel would need a property called "FontSize". Unfortunately, StackPanel doesn't have such a property. Oh man, this is getting hairer than a yeti.

So the question is, "How in the world is this darned thing working?".

The answer is "Dependency Properties".

Note: Try experimenting by specifying a FontSize on the TextBlock and a different FontSize on the Window - you will notice that the child (TextBlock) overrides the parent (Window) - makes complete sense.

A dependency property, put simply, is what you must understand to keep your sanity in WPF. WPF does a lot of stuff under the scenes, and it does so with the help of Dependency Properties. To understand Dependency Properties in further depth, let's pop open my favorite friend - Reflector. If you look at System.Windows.Controls.TextBlock, it has an interesting property specified called "FontSize" defined as follows -

[TypeConverter(typeof(FontSizeConverter)), Localizability(LocalizationCategory.None)]
public double FontSize
{
      get
      {
            return (double) base.GetValue(TextBlock.FontSizeProperty);
      }
      set
      {
            base.SetValue(TextBlock.FontSizeProperty, value);
      }
}

So, the "FontSize" property, seems to set and get the value of another variable called "FontSizeProperty". <--- Read that again 3 times. See anything funny going on here? I'm tellin' ya man, this is hairier than Mrs. Yeti. Well, don't stop here - keep divin'. Let us try and see what "FontSizeProperty" is declared as -

public static readonly DependencyProperty FontSizeProperty;

Very interesting, I must say. If you continue to dive deeper, you will eventually find something similar to -

FontSizeProperty = DependencyProperty.Register("FontSize", typeof(double), typeof(control))

Truthfully, there are many ways to associate a Property (FontSize), with a DependencyProperty (FontSizeProperty). You will find such a property/depdencyProperty combination on the Windows class as well - with the same name "FontSize". WPF uses this information to give you this "automatically set property values" behavior. This is also how changing the brush repaints a window automatically, as I had described in my Freezable WPF objects post earlier. This is also what forms the basis of Animation on WPF. This is something, you've gotta learn, if you care about WPF.

Please post your comments:


Your feedback will be submitted for moderation, and will appear after it is approved.

Name:  
Email (optional): Your email address will not be posted.
URL (optional):
Comments: HTML will be ignored, URLs will be converted to hyperlinks  
Enter the text you see in the box:
 

Site designed and maintained by Sahil Malik | All Rights Reserved. ©2007 WinSmarts.com.