依存関係プロパティをオーバーライドする方法

WPF でカスタムコントロールを作っていると、基本クラスで定義されているプロパティのデフォルト値を変更したり、プロパティの値の変更に対して処理を行いたい場合があります。

しかし、WPF の依存関係プロパティは virtual ではないので、オーバーライドできません。

どうすればいいのか?

DependencyProperty の OverrideMetadata メソッドを使えば可能です。

public partial class SampleControl : UserControl
{
    public SampleControl()
    {
        InitializeComponent();
    }

    static SampleControl()
    {
        SampleControl.BackgroundProperty.OverrideMetadata(
            typeof(SampleControl),
            new FrameworkPropertyMetadata(BackgroundChanged));
    }

    static void BackgroundChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        // UserControl の Background が変更されたら、
        // 中に置かれている TextBox の Background も変更する。
        SampleControl control = (SampleControl)obj;
        control._textBox.Background = (Brush)e.NewValue;
    }
}

カスタムコントロールの static コンストラクタ内で、オーバーライドしたいプロパティの OverrideMetadata メソッドに、クラスの型と FrameworkPropertyMetadata を渡しています。

FrameworkPropertyMetadata ではプロパティ変更時に実行されるコールバックメソッドを指定しています。他にも、デフォルト値や、プロパティ変更時に値を検証するメソッドも指定できます。