独自のユーザーコントロールを作成して利用する際、できることなら xaml 上のプロパティ(属性)に値を設定するだけで動くようにしたいと思い… あれやこれやと実現する方法を調べたので、その結果をまとめておきます。
以下のサンプルでは GreetingMessageControl
を作成します。
この ユーザーコントロール は 独自プロパティ として Locale
があり、この プロパティ に ja
や en
を設定すると 挨拶 が表示されるコントロールです。
目次
- ユーザーコントロールの作成
- xaml
- cs
- ユーザーコントロールの利用
- xaml
ユーザーコントロールの作成
基本的には UserControl
を継承したクラスを作成すれば問題ありません。
依存プロパティを利用できるようにするためには コードビハインド で少し記述が必要になります。
xaml
TextBlock
を1つだけ表示する ユーザーコントロール をデザインしました。
コードビハインドで文字列表示を制御したいので、TextBlock
には x:Name
を指定しています。
GreetingMessageControl.xaml
1 2 3 4 5 6 7 8 9 10 11 | < UserControl x:Class = "WpfApplication2.GreetingMessageControl" 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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
1 2 3 4 5 6 7 8 9 | < Window x:Class = "WpfApplication2.MainWindow" 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 の フォロー」 お願いします!!