Attached Properties in WPF

Attached Properties

Let's start by understanding the Attached Properties. Attached Properties (AP) are again a kind of Dependency Property (DP) in XAML. They can be used to receive a notification of a change of themself since they are a type of Dependency Property but one of the differences that these properties have is that they are not defined in the same class they used, unlike DPs. One of the misconceptions that a WPF developer usually has is that these properties can only be defined in the parent control the control in which we want to use them. One of the examples that comes to our mind when defining an AP is Grids. A Grid.Row or a Grid.Column are an AP that can used in its child control to set the row and column for the child control where it will sit in the control once the rendering is done. So having said that, what most developer's think is that an AP can defined only in the parent control and used in the child control. But this is not the case and I will demonstrate that in an example that I used. But suppose I use the same Attached Property Grid.Row or Grid.Column for the control that is not the child of the Grid, it will not throw an exception. The only result is that it would be meaningless and of no use. As per the MSDN, an AP can be defined in one of the following three contexts:

  • The type that defines the Attached Property is designed so that it can be the parent element of the elements that will set values for the Attached Property. The type then iterates its child objects using internal logic against some object's tree structure, obtains the values and acts on those values in some manner.

  • The type that defines the Attached Property will be used as the child element for a variety of possible parent elements and content models.

  • The type that defines the Attached Property represents a service. Other types set values for the Attached Property. Then, when the element that set the property is evaluated in the context of the service, the Attached Property values are obtained using internal logic of the service class.

The first two definitions are what we think of APs. APs are called “attached” properties because we can attach some behaviour to the control that is originally not expected from that control.

One analogy that I can suggest here is that, what Extension Methods are to classes in C#, is what Attached Properties are to controls in WPF. Both of these are used to extend the behaviour of their functionality.

The way the APs are defined is quite different from DPs and that is what I discussed here.

One difference with DP is that this example calls RegisterAttached() rather than just Register(). The other difference is that this example doesn't have a standard .NET property anymore and instead, there now are static GetAllowOnlyString() and SetAllowOnlyString() methods. That's because you will never set these properties on the TextblockExtension object directly, but instead want to store this value with other properties. It wouldn't make sense to create a standard property at all.

Why we have these two functions defined is that we can get the value of the property attached using the Get() method. One of the uses I can think of for here is to use the APs to get a pure MVVM pattern. We can define an AP of type ICommand and bind some command to the control that can be invoked using that AP. This way we can have more functionality attached to the control without having any code behind events. I will leave this part to the reader to try on their own.

Now I want to discuss one example that I have used to display the usability of Attached Properties. Suppose I have a TextBox control and I want to extend its functionality to accept letters and special symbols but not numeric values.

The AP that I have defined in my class TextBlockExtension.cs is as in the following:

  1. public static bool GetAllowOnlyString(DependencyObject obj)  
  2. {  
  3.    return (bool)obj.GetValue(AllowOnlyStringProperty);  
  4. }  
  5. public static void SetAllowOnlyString(DependencyObject obj, bool value)  
  6. {  
  7.    obj.SetValue(AllowOnlyStringProperty, value);  
  8. }  
  9. // Using a DependencyProperty as the backing store for AllowOnlyString. This enables animation, styling, binding, etc...  
  10. public static readonly DependencyProperty AllowOnlyStringProperty =  
  11. DependencyProperty.RegisterAttached("AllowOnlyString"typeof(bool),typeof(TextblockExtension), new PropertyMetadata(false, AllowOnlyString));  
  12. private static void AllowOnlyString(DependencyObject d, DependencyPropertyChangedEventArgs e)  
  13. {  
  14.    if (d is TextBox)  
  15.    {  
  16.       TextBox txtObj = (TextBox)d;  
  17.       txtObj.TextChanged += (s, arg) =>  
  18.       {  
  19.          TextBox txt = s as TextBox;  
  20.          if (!Regex.IsMatch(txt.Text, "^[a-zA-Z]*$"))  
  21.          {  
  22.             txtObj.BorderBrush = Brushes.Red;  
  23.             MessageBox.Show("Only letter allowed!");  
  24.          }  
  25.       };  
  26.    }  
  27. }  
In the code, as we can see, the AP has the default value of False, in other words we need to provide the APs the value true wherever I want this functionality to work for the TextBox.

In my MainWindow.xaml.cs I have defined my TextBox as in the following:
  1. <TextBox Width="200" Height="50" local:TextblockExtension.AllowOnlyString="True"></TextBox>  
Now after running the application what we will see is that as soon as the user enters the numeric value a MessageBox is shown with the border color of the text box changed to Red. All this is done using the attached behaviour that we defined in the AllowOnlyString AP. Now suppose we want to have this behaviour for all the TextBoxes of the application then we can have the following style defined in some Resource Dictionary of the application or the App.xaml.
  1. <Style TargetType="TextBox">  
  2.    <Style.Setters>  
  3.       <Setter Property="local:TextblockExtension.AllowOnlyString" Value="True"></Setter>  
  4.    </Style.Setters>  
  5. </Style>  
The preceding example shows the strong functionality of Attached Properties that is done without writing any extra code in each class.

Please provide your comments about the article.