忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

DataTriggerの使い方(WPF)

個人的に WPFは覚えたと思ってしばらく経つとすぐ忘れるということを繰り返しています。
恥ずかしながらDataTriggerも以前使ったはずなのに、すっかり使い方を忘れてしまいました。

二度と忘れないよう、DataTriggerの使い方をメモしておこうと思います。
と言ってもしばらく立つと忘れるんでしょうねーと思いつつ。


目的

DataTriggerはどういうときに使うのか?
それはあるデータがある値を取るとき、あることをする、というものです。

なんのこっちゃなので、具体例を出しましょう。
ウィンドウの中にチェックボックスが一つあったとします。

wpfDataTriggerNotChecked.jpg


これにチェックを入れるとCheckBoxのContentプロパティが変わって欲しいとしましょう。

wpfDataTriggerChecked.jpg


Contentプロパティが

""→"Checked!!"

と変わったのです。
チェックを外すとテキストは元に戻ります。
"Checked!!"→""

これを実現するにはC#のコードを書く必要はなく(DataTriggerを使う必要もなく)、下のようなXAMLで十分です。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="150" Width="225">
    <CheckBox>
        <CheckBox.Style>
            <Style TargetType="CheckBox">
                <Style.Triggers>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="Content" Value="Checked!!"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </CheckBox.Style>
    </CheckBox>
</Window>

つまりCheckBoxのIsCheckedがtrueになったとき、CheckBoxのContentを"Checked!!"にする、という意味です。

DataTriggerを使う

さて、上の例ではこのXAMLで十分ですが、実際にはもうちょっと凝ったことをしたくなることがあります。
例えばMVVMパターン。
ViewModelのプロパティXをIsCheckedにバインドして、そしてプロパティXの値を元にトリガー(たとえばTextBlockのTextなんかを変更するのでしょう)を起動すると考えてください。

つまり

CheckBox.IsChecked → ViewModel.X → TextBlock.Text

というようなデータの流れです。

このケースでは、コントロールではなく、ViewModelのプロパティの値によってトリガーを起動する必要があります。
そういったときにDataTriggerが使えます。
 
今度も上と同じ仕様にしてみましょう。
チェックを入れると文字が表示されるのです。
ただし今度はテキストブロックを明示的に使ってみます。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="150" Width="225">
    <Window.Resources>
        <src:TestViewModel x:Key="viewModel"/>

        <Style x:Key="style" TargetType="TextBlock">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsViewModelEnabled}" Value="true">
                    <Setter Property="Text" Value="Checked!!"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    
    <CheckBox DataContext="{StaticResource viewModel}" IsChecked="{Binding IsViewModelEnabled}" >
        <TextBlock Style="{StaticResource style}"/>
    </CheckBox>
</Window>



今度はC#側も必要です。 
ViewModelを使うからです。

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class TestViewModel
    {
        public bool IsViewModelEnabled { get; set; }
    }
}


 
このプログラムは上のプログラムと同じように動作します。
違うのは、ViewModelを介して、動いているというところです。
(と言っても、ViewModelにはプロパティしか有りませんが。)
(不思議なことにINotifyPropertyChangedインターフェースは必要ありません)
 
アプリケーションが動くときにはUIだけで完結するよりもViewModelなC#ロジックで動くことが多いのではないでしょうか。(多分)
そういうときにDataTriggerは役立つかもしれません。

もっともこれ、boolとstringを変換するConverterで同じことが出来ますが。

拍手[3回]

PR