独自のユーザーコントロールを作成して利用する際、できることなら xaml 上のプロパティ(属性)に値を設定するだけで動くようにしたいと思い… あれやこれやと実現する方法を調べたので、その結果をまとめておきます。
以下のサンプルでは GreetingMessageControl を作成します。
この ユーザーコントロール は 独自プロパティ として Locale があり、この プロパティ に ja や en を設定すると 挨拶 が表示されるコントロールです。
目次
- ユーザーコントロールの作成
- xaml
- cs
- ユーザーコントロールの利用
- xaml
ユーザーコントロールの作成
基本的には 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 を作成します。
基底クラスにある GetValue や SetValue を利用します。
プロパティが変更されたときの コールバック を作成する
コード 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>
参考記事
- stack overflow - Setting Custom Properties in UserControl via DataBinding
- stack overflow - How to add custom XAML attributes to a class that inherits UserControl?
- stack overflow - Custom attributes in WPF user control
- Qiita - WPF 依存プロパティの作り方
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!

