Introduction
忘備録。
WPF は見た目を自由に定義できるが、その方法がいくつもある。
- Triger
- Style
- VisualState
加えて、コントロールの見た目を根本的に変えることができる ControlTemplate が絡んでくると、どの方法を使えばいいのかで混乱してしまう。
そんな中で掲題の ControlTemplate 内で DataTrigger を定義し、カスタムコントロールの依存関係プロパティに Binding した場合にはまった場合についてメモ。
サンプルソースは、GitHub に置きました。
What is problem?
ControlTemplate 内にも、当然 DataTrigger を設定することはできるが…
下記は DatTrigger を指定し、カスタムコントロールの依存関係プロパティに Binding した、 「間違った」 Generic.xaml の例。
1 | <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
カスタムコントロールの定義は下記。
1 | using System.Windows; |
Unable to cast object of type ‘System.Windows.TemplateBindingExpression’ to type ‘System.Windows.Data.BindingBase’
実行すると下記のような例外を投げてしまう。
System.Windows.Markup.XamlParseException: ‘’プロパティ ‘System.Windows.DataTrigger.Binding’ の Set で例外がスローされました。’ 行番号 ‘16’、行位置 ‘26’。’
内部例外
InvalidCastException: Unable to cast object of type ‘System.Windows.TemplateBindingExpression’ to type ‘System.Windows.Data.BindingBase’.
げんなりするが、ポイントは、 System.Windows.Data.BindingBase を System.Windows.TemplateBindingExpression にキャストできない、という点。
ControlTemplate 内で、カスタムコントロールに定義した依存関係プロパティに Binding するには、TemplateBinding を使うのが仕様だが、こと DataTrigger に対しては通用しない。
この場合、カスタムコントロールに定義した依存関係プロパティに反応するようにするには、シンプルに下記でいい。
1 | - <DataTrigger Binding="{TemplateBinding Checked}" |
ArgumentException: 式の型は、有効な Style 値ではありません。
前述のように直すと今度は違う例外を投げてしまう。
System.Windows.Markup.XamlParseException: ‘’プロパティ ‘System.Windows.Setter.Value’ の Set で例外がスローされました。’ 行番号 ‘20’、行位置 ‘30’。’
内部例外
ArgumentException: 式の型は、有効な Style 値ではありません。
今回は Setter の使い方がおかしいことは理解できる。
下記のように直す。
1 | <DataTrigger Binding="{Binding Checked}" |
以上で DataTrigger がカスタムコントロールに定義した依存関係プロパティに反応して動作するようになる。
Source Code
https://github.com/takuya-takeuchi/Demo/tree/master/WPF/17_DataTriggerInControlTemplate