#160 – Be Careful When Setting Dependency Property Values from a DependencyObject Constructor

You should normally avoid calling any virtual methods in a C# class constructor.  Your constructor might get called during construction of a derived class, before the derived class has finished initializing everything that it needs to initialize.  If the derived class also overrides the virtual method that you’re calling, that method could end up getting called before the derived class has finished initializing everything (in its constructor).

If you use FxCop to check your code, this will be caught by the DoNotCallOverridableMethodsInConstructors rule.

This rule applies to WPF.  If you set the value of a dependency property in a constructor, virtual methods or callbacks in the property system may end up getting called.

The best way to avoid the problem is to follow the following rule:

  • Initialize all objects that might be used by property system callbacks in your default (parameterless) constructor

See also: Safe Constructor Patterns for DependencyObjects

#159 – Creating a Read-Only Dependency Property

Creating a custom dependency property that is read-only is slightly different from creating a standard dependency property.

  • Use DependencyProperty.RegisterReadOnly, rather than Register
  • Create an internal static copy of a DependencyPropertyKey in addition to a public static DependencyProperty
  • Make the CLR property wrapper read-only

For example, assume that we want to add a read-only IQ property to our Person class.

We register the property as read-only and retrieve a DependencyPropertyKey.

        internal static readonly DependencyPropertyKey IQPropertyKey =
            DependencyProperty.RegisterReadOnly("IQ", typeof(int), typeof(Person), new PropertyMetadata(100));

Although the key is private, we make the property public.

        public static readonly DependencyProperty IQProperty =
            IQPropertyKey.DependencyProperty;

We can still set the value internally, by using the key.

public Person(string first, string last, int iq)
{
    FirstName = first;
    LastName = last;
    SetValue(IQPropertyKey, 100);
}

Finally, we provide a CLR property wrapper.

        public int IQ
        {
            get { return (int)GetValue(IQProperty); }
        }

#158 – When to Create a Custom Dependency Property

When you’re implementing a new class and creating properties of that class, you need to decide for each property whether to make it a full-fledged WPF dependency property.

If a property is a standard CLR property, rather than a dependency property, you can still set property values from XAML.

But you might want to create a custom dependency property if you want your class to do any of the following:

#157 – You Can Set Standard CLR Properties from XAML

If you create a custom class, you can instantiate instances of that class from XAML by adding the object to a resource dictionary.

    <Window.Resources>
        <m:Person x:Key="perBill" FirstName="William" LastName="Shakespeare" />
    </Window.Resources>

You might wonder whether your properties have to be WPF dependency properties in order to set their values from XAML.  It turns out that the properties on the custom class do not have to be dependency properties in order to be set from XAML.  They can be standard CLR properties.

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Person()
        {
        }
    }
Follow

Get every new post delivered to your Inbox.

Join 365 other followers