[WPF]DataTriggerを使って、ViewModelのフラグ等にバインドして、見た目を変化させる


やりたいこと

ビューモデルのフラグなどにバインドして、画面の見た目を変えたい。

やり方

DataTriggerというのを使って実現できた。Styleの中にDataTriggerを組み込んでやる感じ。
似たようなものに、ただのTriggerがあるが、こちらはそのコントロール自身のプロパティを見て、自身のほかのプロパティを切り替えるようなことができるっぽい。

下記に、その両方のサンプルを載せる。

View(xaml)

UserControl1.xaml
<UserControl x:Class="PrismSample.Views.UserControl1"
             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" 
             xmlns:local="clr-namespace:PrismSample.Views"
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="Beige">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="60"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <!-- DataTrigger -->
        <Ellipse Grid.Column="1" StrokeThickness="5" Stroke="Black">
            <Ellipse.Style>
                <Style TargetType="Ellipse">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ColorChangeFlag}" Value="true">
                            <Setter Property="Fill" Value="Blue"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>

        <!-- PropertyTrigger -->
        <Ellipse Grid.Column="0" StrokeThickness="5" Stroke="Black">
            <Ellipse.Style>
                <Style TargetType="Ellipse">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Fill" Value="Red"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Ellipse.Style>
        </Ellipse>

        <!-- ボタン -->
        <Button Grid.Row="1" Grid.ColumnSpan="2" Content="ボタン" Command="{Binding ButtonCommand}"/>
    </Grid>
</UserControl

※Prismを使っているので、画面はUserControlで作る。

ViewModel

UserControl1ViewModel.cs
using Microsoft.Practices.Unity;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;

namespace PrismSample.ViewModels
{
    class UserControl1ViewModel : BindableBase, INavigationAware
    {
        // ボタン押下時処理
        public DelegateCommand ButtonCommand { get; }

        // ★〇の色を切り替えるためのフラグ
        private bool _colorChangeFlag = false;
        public bool ColorChangeFlag
        {
            get { return _colorChangeFlag; }
            set { SetProperty(ref _colorChangeFlag, value); }
        }

        // コンストラクタ
        public UserControl1ViewModel()
        {
            this.ButtonCommand = new DelegateCommand(() =>
            {
                // ★ボタンをおしたら、フラグが切り替わる
                ColorChangeFlag = !ColorChangeFlag;
            });
        }

        // --------- Prismお決まり部分 -------------

        [Dependency]
        public IRegionManager RegionManager { get; set; }

        public bool IsNavigationTarget(NavigationContext navigationContext) => false;
        public void OnNavigatedFrom(NavigationContext navigationContext) { }
        public void OnNavigatedTo(NavigationContext navigationContext) { }
    }
}

できあがり

■DataTriggerについて
ボタンを押すと、DataTriggerにバインドしているViewModelのフラグが切り替わって、画面に反映され、右側の円が青くなる。

■PropertyTriggerについて
Ellipseのコントロール自身が持っている、マウスが上に来たらtrueになるフラグIsMouseOverがtrueになったら、自分の背景色のプロパティFillをRedにする。

参考

DataTriggerの使い方(WPF)
http://memeplex.blog.shinobi.jp/wpf/datatrigger%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%EF%BC%88wpf%EF%BC%89

コード