Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

View を支える依存関係プロパティ

はじめに

オレオレ解釈の覚書 その11

依存関係プロパティについてです。

本文

依存関係プロパティとは簡単に言えば Xaml 上でバインドできるコントロールのプロパティです。身近なところで言えば TextBox.Text や CheckBox.IsChecked などがこれに当たります。その実体は DependencyProperty という静的なフィールドで、DependencyObject から派生したクラスで定義します。例えば TextBox.Text であれば以下のようになります。(実際の System.Windows.Controls.TextBox とは異なります。あくまでイメージです。)

TextBox
using System.Windows;

namespace TestApp.Views.Controls
{
    public class TextBox : DependencyObject
    {
        // 依存関係プロパティ
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register(
                "Text",
                typeof(string),
                typeof(TextBox));

        // CLR ラッパープロパティ
        public string Text
        {
            get => (string) this.GetValue(TextProperty);
            set => this.SetValue(TextProperty, value);
        }
    }
}

依存関係プロパティは DependencyProperty にメタ情報を渡して初期化するだけで、Xaml からバインドするための準備ができてしまいます。ただし、プログラム(C#側)からアクセスする際には、DependencyObject のメソッドを経由する必要があり、通常のプロパティと使用感が合いません。例のようにラッパープロパティを用意してインターフェースに統一感を持たせるのが一般的で、これによりコントロールの利用者は依存関係プロパティの存在を意識せずにアクセスすることができます。

宣伝

上記のようにすれば依存関係プロパティを定義できますが、初期化のくだりは多くの場合で規則的になり、いくつも用意する際は面倒ですし、バグの温床にもなります。拙作ですが、NuGet にて公開中の下記のライブラリでは、初期化の際に要求されるメタ情報を省略することができます。ラッパープロパティを用意することが暗黙のルールであることを利用し、必要な情報を補っています。

TextBox
using Plow.Wpf;
using System.Windows;

namespace TestApp.Views.Controls
{
    public class TextBox : DependencyObject
    {
        // 依存関係プロパティ
        public static readonly DependencyProperty TextProperty =
            DependencyPropertyExtensions.Register();

        // CLR ラッパープロパティ
        public string Text
        {
            get => (string) this.GetValue(TextProperty);
            set => this.SetValue(TextProperty, value);
        }
    }
}

おわりに

ViewModel で登場した変更通知プロパティとは異なり、依存関係プロパティはほとんどのコントロールで必要なものがある程度用意されているため、新たに追加する機会は少ないかもしれません。とはいえ、ユーザーコントロールとしてまとめた際や、既存のコントロールを拡張する場合に登場するため、頭の片隅には置いておきたいですね。

次回はこれを応用した添付プロパティについてまとめます。

kawasawa
C#Beginner / 尊敬するプログラマはMSのかずきさん(@okazuki) / ストアで自作アプリ公開してます
https://kawasawa.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away