WPF: Implementing dependency properties

When you define your own properties and want them to support many aspects of Windows Presentation Foundation (WPF) functionality, including styles, data binding, inheritance, animation, and default values, you should implement them as a dependency property.

In this example, we show how we can create a Textblock that is bound to a button and how we back up the storage of the Text in the Textblock with a dependency property.

The following example defines the Year dependency property, and shows the relationship of the DependencyProperty identifier to the property that it backs.

To make Year into a dependency property, we need to create an identifier.  This is done by registering it as YearProperty.

public int Year
        {
            get { return (int)GetValue(YearProperty); }
            set { SetValue(YearProperty, value); }
        }           

        // Using a DependencyProperty as the backing store for YearProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty YearProperty =
            DependencyProperty.Register("Year", typeof(int), typeof(SimpleControl), new PropertyMetadata(2014));

Lets’ got through the steps in creating this simple application.

1.  Create a WPF application called DependencyProperty.

2.  We now add a User Control and register it as a dependency property.

3.  From the Solution Explorer, right click on it.  Then go to Add – User Control (WPF) – Solution Explorer.

add

4.  Give it a name such as SimpleControl

addusercontrol

5.  We’ll add a dependency property to the SimpleControl class. A dependency property needs to be “registered” with the property system. Open the SimpleControl.xaml.cs file and type propdp just after the closing brace of the constructor. This is how it would look in the Visual Studio editor:

Propd

 

6.  This is a code snippet that helps with the details of properly registering the property. Press Tab twice; the code snippet is expanded to something like the following:

        public int MyProperty
        {
            get { return (int)GetValue(MyPropertyProperty); }
            set { SetValue(MyPropertyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));

7.  We need to make some modifications to the above code.

  • Change MyProperty to YearProperty
  • Change the only 0 in the above code to 2014, which is the current year.

8.  After the 2 changes above, the code for SimpleControl.xaml.cs is

using System.Windows;
using System.Windows.Controls;

namespace DependencyProperties
{
    /// <summary>
    /// Interaction logic for SimpleControl.xaml
    /// </summary>
    public partial class SimpleControl : UserControl
    {
        public SimpleControl()
        {
            InitializeComponent();
        }
                    
        public int Year
        {
            get { return (int)GetValue(YearProperty); }
            set { SetValue(YearProperty, value); }
        }           

        // Using a DependencyProperty as the backing store for YearProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty YearProperty =
            DependencyProperty.Register("Year", typeof(int), typeof(SimpleControl), new PropertyMetadata(2014));

    }
}

9.  We should add a StackPanel into MainWindow.xaml as below.

<Window x:Class="DependencyProperties.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DependencyProperties"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <local:SimpleControl x:Name="simple" />
            <TextBlock Text="{Binding Year, ElementName=simple}" FontSize="30" />
            <Button Content="Next Year" Click="OnChangeValue" FontSize="20" Width="150" Margin="0,100"/>
        </StackPanel>
    </Grid>
</Window>

10.  As for the MainWindow.xaml.cs, it shoule look like below.

using System.Windows;

namespace DependencyProperties
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OnChangeValue(object sender, RoutedEventArgs e)
        {
            simple.Year++;
        }
    }
}

11.  Run the code and the output looks like below.

dependency

 

 

Series Navigation<< WPF: Master detail for a class with data
WPF: Attached property >>