This is an old revision of the document!


Dependency Properties

If data binding is required to certain properties, then these need to be implemented as Dependency Properties.

Here is a good example (from: C# is Easy: Dependency Property):

public class Button : ButtonBase
{
  // The dependency property
  public static readonly DependencyProperty IsCancelProperty;
 
  // Constructor
  static Button()
  {
    // Register the property
    Button.IsCancelProperty = DependencyProperty.Register(“IsCancel”,
        typeof(bool), typeof(Button),
        new FrameworkPropertyMetadata(false,
        new PropertyChangedCallback(OnIsDefaultChanged)));}
 
  // A .NET property wrapper (not must)
  public bool IsCancel
  {
    get { return (bool)GetValue(Button.IsCancelProperty ); }
    set { SetValue(Button.IsCancelProperty , value); }
  }
 
  // A property changed callback (not must)
  private static void OnIsCancelChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e) {}}

Alternatively:

public class Button : ButtonBase
{
  // The dependency property declaration, and registration
  public static readonly DependencyProperty IsCancelProperty = DependencyProperty.Register(“IsCancel”,
        typeof(bool), typeof(Button),
        new FrameworkPropertyMetadata(false,
        new PropertyChangedCallback(OnIsDefaultChanged)));
 
  // A .NET property wrapper (not must)
  public bool IsCancel
  {
    get { return (bool)GetValue(Button.IsCancelProperty ); }
    set { SetValue(Button.IsCancelProperty , value); }
  }
 
  // A property changed callback (not must)
  private static void OnIsCancelChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e) 
  {
       ... 
  }
 
  // Constructor
  static Button()
  {
  }
 
  …
}

IMPORTANT: The accessor property is fine to use, but the XAML code will only call the SetValue() and GetValue() methods directly, so make sure that no other code gets added to the accessor property, to make sure both work the same.

Example

public class Employee : DependencyObject
{
    private static readonly DependencyProperty EmpIdProperty =
        DependencyProperty.Register("EmpId", typeof(int), typeof(Employee),
        new PropertyMetadata(0,
            new PropertyChangedCallback(EmpIdCallBack),
            new CoerceValueCallback(CoerceEmpId)));
 
    private static readonly DependencyProperty NameProperty =
        DependencyProperty.Register("Name", typeof(string), typeof(Employee));
 
    private static readonly DependencyProperty DepartmentProperty =
        DependencyProperty.Register("Department", typeof(string), typeof(Employee));
 
    private static readonly DependencyProperty CompanyProperty =
        DependencyProperty.Register("Company", typeof(string), typeof(Employee),
        new PropertyMetadata("WPF In Corp"));
 
    // If employee id is greater than 1000 then make it 1000
    static void EmpIdCallBack(DependencyObject d,
        DependencyPropertyChangedEventArgs args)
    {
        Employee emp = (Employee)d;
 
        if (emp.EmpId >= 1000)
        {
            emp.EmpId = 1000;
        }
    }
 
    // If the employee Id is negative then make it positive
    static Object CoerceEmpId(DependencyObject d, Object baseValue)
    {
        int value = (int)baseValue;
 
        if (value < 0)
            return value * -1;
        else
            return value;
    }
 
    public int EmpId
    {
        get { return (int)GetValue(EmpIdProperty); }
        set { SetValue(EmpIdProperty, value); }
    }
 
    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
 
    public string Department
    {
        get { return (string)GetValue(DepartmentProperty); }
        set { SetValue(DepartmentProperty, value); }
    }
 
    public string Company
    {
        get { return (string)GetValue(CompanyProperty); }
        set { SetValue(CompanyProperty, value); }
    }
}

Source: Zeeshan Amjad: Dependency Property Metadata

See Also