WPF - Dependency Properties

In WPF applications, dependency property is a specific type of property, which extends CLR property. It takes the advantage of specific functionalities, which are available in WPF property system.

A class, which defines a dependency property must be inherited from the DependencyObject class. Many of UI controls class, which are used in XAML are derived from DependencyObject class and they support dependency properties, e.g. Button class supports the IsMouseOver dependency property.

XAML code given below creates a button with some properties. 

  1. <Window x:Class="WPFDependencyProperty.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WPFDependencyProperty" Title="MainWindow" Height="350" Width="604">  
  2.     <Grid>  
  3.         <Button Height="40" Width="175" Margin="10" Content="Dependency Property"> <Button.Style>  
  4.   
  5. <Style TargetType="{x:Type Button}">  
  6.   
  7. <Style.Triggers>  
  8.   
  9. <Trigger Property="IsMouseOver" Value="True">  
  10.   
  11. <Setter Property="Foreground" Value="Red"/>  
  12.   
  13. </Trigger>  
  14.   
  15. </Style.Triggers>  
  16.   
  17. </Style>  
  18.   
  19. </Button.Style>  
  20.   
  21. </Button> </Grid>  
  22. </Window>   

The x:Type markup extension in XAML has a similar functionality like typeof() in C#. It is used when the attributes are specified, which takes the type of the object such as <Style

  1. TargetType="{x:Type Button}">  

When the code given above is compiled and executed, you will get MainWindow given below. When the mouse is over the button, it will change the foreground color of a button. When the mouse leaves the button, it changes back to its original color.

 

Why do we need dependency properties

Dependency property gives you all kinds of benefits when you use it in your Application. Dependency property can be used over CLR property in the scenarios given below.

  • If you want to set the style.
  • If you want data binding.
  • If you want to set with a resource (a static or a dynamic resource).
  • If you want to support an animation.

Basically, Dependency properties offer a lot of functionalities, which you will not get by using a CLR property.

The main difference between dependency properties and other CLR properties are listed below.

  • CLR properties can directly read/write from the private member of a class by using getter and setter. In contrast, dependency properties are not stored in a local object.
  • Dependency properties are stored in a dictionary of key/value pairs, which is provided by the DependencyObject class. It also saves a lot of memory because it stores the property when changed. It can be bound in XAML as well.

Custom Dependency properties

In .NET framework, custom dependency properties can also be defined. Follow the steps given below to define custom dependency property in C#.

  • Declare and register your dependency property with system call register.
  • Provide the setter and getter for the property.
  • Define a static handler, which will handle any changes that occur globally
  • Define an instance handler, which will handle any changes that occur to that particular instance.

C# code given below defines a dependency property to set SetText property of the user control. 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.Windows;  
  7. using System.Windows.Controls;  
  8. using System.Windows.Data;  
  9. using System.Windows.Documents;  
  10. using System.Windows.Input;  
  11. using System.Windows.Media;  
  12. using System.Windows.Media.Imaging;  
  13. using System.Windows.Navigation;  
  14. using System.Windows.Shapes;  
  15. namespace WpfApplication3 {  
  16.     /// <summary>  
  17.     /// Interaction logic for UserControl1.xaml  
  18.     /// </summary>  
  19.     public partial class UserControl1: UserControl {  
  20.         public UserControl1() {  
  21.             InitializeComponent();  
  22.         }  
  23.         public static readonly DependencyProperty SetTextProperty = DependencyProperty.Register("SetText"typeof(string), typeof(UserControl1), new PropertyMetadata(""new PropertyChangedCallback(OnSetTextChanged)));  
  24.         public string SetText {  
  25.             get {  
  26.                 return (string) GetValue(SetTextProperty);  
  27.             }  
  28.             set {  
  29.                 SetValue(SetTextProperty, value);  
  30.             }  
  31.         }  
  32.         private static void OnSetTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {  
  33.             UserControl1 UserControl1Control = d as UserControl1;  
  34.             UserControl1Control.OnSetTextChanged(e);  
  35.         }  
  36.         private void OnSetTextChanged(DependencyPropertyChangedEventArgs e) {  
  37.             tbTest.Text = e.NewValue.ToString();  
  38.         }  
  39.     }  
  40. }   

Here is XAML file in which TextBlock is defined as a user control and the Text property will be assigned to it by SetText dependency property.

XAML code given below creates a user control and initializes its SetText dependency property. 

  1. <Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="clr-namespace:WpfApplication3" Title="MainWindow" Height="350" Width="604">  
  2.     <Grid>  
  3.         <views:UserControl1 SetText="Hellow World" /> </Grid>  
  4. </Window>  

Let's run this Application. You can immediately observe that in our MainWindow, the dependency property for the user control has been successfully used as a text.