User Controls and Dependency Properties - Page 7
       by kirupa  |  19 November 2007

In the previous page, we began to take a look at our code that makes up our dependency property. We started to look at the various argument passed to our Register method, so let's continue from where we left off:

public static readonly DependencyProperty InfoTextProperty =
   DependencyProperty.Register(
      "InfoText",
      typeof(string),
      typeof(InfoRectangle),
      new FrameworkPropertyMetadata(
         new PropertyChangedCallback(ChangeText)));

The second argument refers to the type of our dependency property. In our case, InfoText is a string, and we use the typeof function to specify the type - hence why we have typeof(string) specified instead of just string.


public static readonly DependencyProperty InfoTextProperty =
   DependencyProperty.Register(
      "InfoText",
      typeof(string),
      typeof(InfoRectangle),
      new FrameworkPropertyMetadata(
         new PropertyChangedCallback(ChangeText)));

The third argument looks similar to what we wrote earlier. What you are specifying is the type of the class that owns this dependency property. In this case, you are declaring this dependency property inside your InfoRectangle user control, and that is the value you provide here.


public static readonly DependencyProperty InfoTextProperty =
   DependencyProperty.Register(
      "InfoText",
      typeof(string),
      typeof(InfoRectangle),
      new FrameworkPropertyMetadata(
         new PropertyChangedCallback(ChangeText)));

The final argument to our Register method is defining our dependency property's metadata. This information is used internally for various uses such as determining the initial value of your dependency property, how it gets redrawn, etc, and there are numerous overloads that provide you with access to various combinations of things you can specify as metadata. Our needs are fairly simple, so my only argument is to create a new PropertyChangedCallback object with a function called ChangeText as its argument.

Your PropertyChangedCallback object is fired every time your dependency property InfoText is changed. That means, when you change the value of your text from within Blend, your PropertyChangedCallback receives notification and calls whatever method it is setup to call - in our case, ChangeText! Let's take a look at our ChangeText method in greater detail.


Part 3: The Property Callback Method
The property callback method is an optional method you can specify to handle any changes made to your dependency property. Earlier, you created a new PropertyChangedCallback object with the ChangeText method specified as the handler for any changes:

private static void ChangeText(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
(source as InfoRectangle).UpdateText(e.NewValue.ToString());
}

Our ChangeText method isn't your standard, run-of-the-mill method. It resembles an event handler in many ways, and because it is a static method, you cannot directly reference any object inside your current InfoRectangle class. That explains the weird syntax where I am casting our source input argument in terms of InfoRectangle:

(source as InfoRectangle).UpdateText(e.NewValue.ToString());

Using as ObjectType for casting a variable is another way of writing the above as:

((InfoRectangle) source).UpdateText(e.NewValue.ToString());

The last thing to observe from the above line of code is that I am making a call to our UpdateText method, and I pass in our event argument's NewValue method as a string: e.NewValue.ToString(). If for some reason you wanted the old value stored by your dependency property, you could always use e.OldValue. Let's look at our UpdateText method now.


private void UpdateText(string NewText)
{
InfoLabel.Content = NewText;
}

Our UpdateText function is a normal private void function. That means that you can access your current variables and design elements without having to do any of the casting wizardry that you did earlier. What I am doing is setting our InfoLabel's Content property to the new value passed in by our ChangeText property. This allows the actual content in our label to be updated when our dependency property has been updated.


Quick Recap
So, let's recap at a higher level so that you understand how all of these various pieces work. Our user control used a label to display some text. What we wanted to do is make it possible to set our text's value directly via XAML using Blend. The way to do that would be to create a dependency property that, when changed, would update your label's content based on what you entered.

The dependency property we created is called InfoText. First you created the CLR wrapper that used GetValue and SetValue to send or retrieve any information to the WPF property system via code. The critical piece was our field declaration where you created a DependencyProperty object called InfoTextProperty that specifies various characteristics of your dependency property. One characteristic was the PropertyCallback method that calls a method you specify each time your dependency property is modified. The method that received the property changed notification in our case was ChangeText, and that method in turn did the remaining work required to display some new text in our user control.

Onwards to the next page!

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.