WPF Cookbook #2: Dependency Properties Explained

November 6, 2025

In the previous article, we explored how to create custom type instances in XAML. In this article, let's take a look at Dependency Properties (DPs) - the foundational concept that powers bindings, styles, animations, property inheritance, and templates in WPF.


đź§  What is a Dependency Property?

A Dependency Property is a property managed by the WPF property system.
Instead of storing values in a private field, WPF keeps them in a centralized property store that evaluates the effective value by combining multiple sources:

  • Local values (including {Binding} and values set via SetValue — the method used to assign values to DPs in code)
  • Styles & templates (setters, triggers)
  • Value inheritance (e.g., FontSize flowing down the visual tree)
  • Default values from metadata
  • Animations
  • Coercion and validation hooks

Think of DPs as “properties with superpowers” that participate in every layer of the WPF pipeline.


âť“ Why not just CLR properties?

Plain C# properties:

  • ❌ Don’t support XAML {Binding} on controls
  • ❌ Can’t be styled, animated, or inherited
  • ❌ Don’t trigger layout or visual updates automatically
  • ❌ Aren’t recognized by the WPF property system

DPs provide:

  • âś… Binding, styling, templating, and animation
  • âś… Default values via metadata
  • âś… Automatic layout invalidation (AffectsMeasure, AffectsArrange, AffectsRender)
  • âś… Built-in change notifications
  • âś… Value coercion & validation

🎬 Watch the Demo

Here’s a basic example of how to define a Dependency Property in a custom control


⚖️ How WPF decides the final value

When multiple inputs exist, WPF determines the final value based on precedence:

  1. Animations (if active)
  2. Local value (including {Binding} and SetValue)
  3. Template/Style triggers and setters
  4. Inherited value (from parent)
  5. Default value (from property metadata)

Coercion can adjust the chosen value to stay within a valid range.


🎯 TL;DR

  • Use a Dependency Property if it needs to participate in binding, styles, templates, animations, default values, or property inheritance.
  • Use a CLR property + INotifyPropertyChanged for ViewModels.
  • DPs only exist on classes derived from DependencyObject (like FrameworkElement or Control).

Here’s the source code used in the demo:

đź§± Project Setup

DependencyPropertyDemo/
├── DependencyPropertyDemo.csproj
├── App.xaml
├── MainWindow.xaml
└── MainWindow.xaml.cs

đź’» MainWindow.xaml.cs

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

        public int MyValue
        {
            get { return (int)GetValue(MyValueProperty); }
            set { SetValue(MyValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Age.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyValueProperty =
            DependencyProperty.Register("Age", typeof(int), typeof(MainWindow), new PropertyMetadata(25));

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyValue++;
        }
    }
}

🪄 MainWindow.xaml

Here we add a Person object directly inside a Label.

<Window x:Class="DependencyPropertyDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DependencyPropertyDemo"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="300"
        Width="300"
        FontSize="30">
    <StackPanel Orientation="Vertical"
                VerticalAlignment="Center"
                HorizontalAlignment="Center">
        <Button Content="Click Me"
                Click="Button_Click"
                FontSize="16"
                Width="100"
                Height="30"
                Margin="10" />
        <TextBlock x:Name="myTextBlock"
                   Text="{Binding MyValue}"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   FontSize="{Binding MyValue}"
                   Margin="10" />
    </StackPanel>
</Window>