WPF で 依存プロパティ が 使える ユーザーコントロール の 作成方法

0 件のコメント

独自のユーザーコントロールを作成して利用する際、できることなら xaml 上のプロパティ(属性)に値を設定するだけで動くようにしたいと思い… あれやこれやと実現する方法を調べたので、その結果をまとめておきます。

以下のサンプルでは GreetingMessageControl を作成します。 この ユーザーコントロール は 独自プロパティ として Locale があり、この プロパティ に jaen を設定すると 挨拶 が表示されるコントロールです。

目次

ユーザーコントロールの作成

基本的には UserControl を継承したクラスを作成すれば問題ありません。 依存プロパティを利用できるようにするためには コードビハインド で少し記述が必要になります。

xaml

TextBlock を1つだけ表示する ユーザーコントロール をデザインしました。 コードビハインドで文字列表示を制御したいので、TextBlock には x:Name を指定しています。

GreetingMessageControl.xaml

<UserControl x:Class="WpfApplication2.GreetingMessageControl"
             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="30" d:DesignWidth="120">
    <Grid>
        <TextBlock x:Name="txt" VerticalAlignment="Center" HorizontalAlignment="Center"/>
    </Grid>
</UserControl>

cs

Locale プロパティ を利用できるようにするだけでそれなりに記述がありました。 何はともあれまずはサンプルコードです。

GreetingMessageControl.xaml.cs

namespace WpfApplication2
{
    using System.Windows;
    using System.Windows.Controls;

    public partial class GreetingMessageControl : UserControl
    {
        public static readonly DependencyProperty LocaleProperty = DependencyProperty.Register(
            "Locale",
            typeof(string),
            typeof(GreetingMessageControl),
            new PropertyMetadata(
                string.Empty,
                new PropertyChangedCallback((sender, e) =>
                {
                    (sender as GreetingMessageControl).OnLocalePropertyChanged(sender, e);
                })));

        public GreetingMessageControl()
        {
            this.InitializeComponent();
        }

        public string Locale
        {
            get { return (string)this.GetValue(GreetingMessageControl.LocaleProperty); }
            set { this.SetValue(GreetingMessageControl.LocaleProperty, value); }
        }

        private void OnLocalePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var message = string.Empty;

            switch (e.NewValue.ToString())
            {
                case "ja":
                    message = "こんにちは";
                    break;
                case "en":
                    message = "Hello";
                    break;
                default:
                    break;
            }

            this.txt.Text = message;
        }
    }
}

ポイントは以下の3点になると思います。

  • static readonly な DependencyProperty を作成する
  • プロパティ を作成する
  • プロパティが変更されたときの コールバック を作成する

static readonly な DependencyProperty を作成する

コード 8 - 17 行目 LocaleProperty クラス変数 部分になります。 DependencyProperty.Register メソッド の 第4引数 に渡している PropertyMetadata で プロパティ が変更された際の コールバック を指定しています。 できれば 「static な メソッド」 ではなく 「インスタンス メソッド」 を利用したいので、インスタンスに変換して呼び出すように記載しています。

プロパティ を作成する

コード 24 - 28 行目 Locale プロパティ 部分になります。 前述で作成した DependencyProperty に対する setter/getter を作成します。 基底クラスにある GetValueSetValue を利用します。

プロパティが変更されたときの コールバック を作成する

コード 30 - 47 行目 OnLocalePropertyChanged メソッド 部分になります。 変更された値は e.NewValue で取得できます。 取得した値を適切な値にキャストして処理を記載しています。

ユーザーコントロールの利用

前述で作成した GreetingMessageControl を利用してみます。 まずは 名前空間 を利用できるよう xmlns:local を追記します。 次に、追加した名前空間を利用して local:GreetingMessageControl を配置します。 依存プロパティを指定すれば、画面上ですぐに反映していることが確認できます。

MainWindow.xaml

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <local:GreetingMessageControl Locale="en" />
    </Grid>
</Window>

参考記事