Help us understand the problem. What is going on with this article?

WPF 依存プロパティの作り方

More than 5 years have passed since last update.

WPFの依存プロパティの作成方法のサンプルです。

サンプルプログラム

テキストを表示するUserControlを作成する。
表示するテキストはTitleプロパティで指定する。
このTitleプロパティは依存プロパティとして実装する。

DependencyPropertyTestControl.xaml.cs
// UserControlのコードビハインド
public partial class DependencyPropertyTestControl : UserControl
{
    // 1. 依存プロパティの作成
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register("Title", 
                                    typeof(string),
                                    typeof(DependencyPropertyTestControl),
                                    new FrameworkPropertyMetadata("Title", new PropertyChangedCallback(OnTitleChanged)));

    // 2. CLI用プロパティを提供するラッパー
    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    }

    // 3. 依存プロパティが変更されたとき呼ばれるコールバック関数の定義
    private static void OnTitleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        // オブジェクトを取得して処理する
        DependencyPropertyTestControl ctrl = obj as DependencyPropertyTestControl;
        if (ctrl != null)
        {
            ctrl.TitleTextBlock.Text = ctrl.Title;
        }
    }

    // コンストラクタ
    public DependencyPropertyTestControl()
    {
        InitializeComponent();
        Title = "Set Title Property";
    }
}
DependencyPropertyTestControl.xaml
<UserControl x:Class="DependencPropertyTest.DependencyPropertyTestControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="50" d:DesignWidth="300">
    <Grid>
        <TextBlock Name="TitleTextBlock" Text="Set Title Property" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="18" FontWeight="Bold" />
    </Grid>
</UserControl>
MainWindow.xaml
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DependencPropertyTest" 
        x:Class="DependencPropertyTest.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <!-- ViewModelをリソースとして生成 -->
        <local:MainWindowViewModel x:Key="ViewModel" />
    </Window.Resources>
    <Grid DataContext="{StaticResource ViewModel}">
      <!-- 作成したサンプルのUserControl : 依存プロパティにViewModelのプロパティをバインドする -->
        <local:DependencyPropertyTestControl Title="{Binding Title}" />
    </Grid>
</Window>
MainWindowViewModel.cs
// ViewModel
class MainWindowViewModel : WindowViewModelBase
{
    // データバインディング用のプロパティ
    public string Title
    {
        get { return GetDataBindItem<string>("Title").Value; }
        private set { GetDataBindItem<string>("Title").Value = value; }
    }

    // コンストラクタ
    public MainWindowViewModel()
    {
        CreateDataBindItem<string>("Title", "Depedency Property Test");
    }
}

コードの説明

1. 依存プロパティの作成

DependencyPropertyクラスの静的メソッドDependencyProperty.Registerを呼び出して、依存プロパティの生成と登録を行います。
生成されたインスタンスは、public static readonly DependencyPropertyなメンバー変数に保持しておきます。この時、変数の名称は「依存プロパティ名」+「Property」でなければいけません。

DependencyProperty.Registerには、いくつかのオーバーロードが存在しますが、このサンプルではプロパティの名称、プロパティの型、プロパティを所有するクラスの型の他にプロパティの付随情報を保持するFrameworkPropertyMetadataクラスのインスタンスにプロパティの初期値とプロパティの値が変更された場合に呼び出されるコールバック関数を指定して渡しています。

public static readonly DependencyProperty TitleProperty =
    DependencyProperty.Register("Title",                                 // プロパティ名
                                typeof(string),                          // プロパティの型
                                typeof(DependencyPropertyTestControl),   // プロパティを所有するクラス
                                new FrameworkPropertyMetadata("Title", new PropertyChangedCallback(OnTitleChanged))); // メタ情報

MSDN:DependencyProperty.Register メソッド

2. コードからアクセスするためのプロパティの作成

コードから依存プロパティにアクセスするには、DependencyObject.GetValue()DependencyObject.SetValue()を利用しないといけないので、通常のプロパティと同様にアクセスできるようにアクセサを定義してやります。

public string Title
{
    get { return (string)GetValue(TitleProperty); }
    set { SetValue(TitleProperty, value); }
}

MSDN:DependencyObject.GetValue メソッド
MSDN:DependencyObject.SetValue メソッド

3.依存プロパティが変更されたとき呼ばれるコールバック関数

DependencyProperty.Registerで依存プロパティを生成・登録するさい、FrameworkPropertyMetadataの属性として指定したプロパティ変更時の
コールバック関数です。依存プロパティの値が変更された場合に呼び出されます。

private static void OnTitleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    // オブジェクトを取得して処理する
    DependencyPropertyTestControl ctrl = obj as DependencyPropertyTestControl;
    if (ctrl != null)
    {
        ctrl.TitleTextBlock.Text = ctrl.Title;
    }
}
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした