忍者ブログ

Memeplexes

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

SilverlightのDataTrigger

SilverlightでDataTrigger

以前
、WPFでDataTriggerを使いました。
今回はSilverlightでDataTriggerを使います。

しかし、SiverlightにはWPFのようなDataTriggerはありません。
(SilverlightはWPFの別バージョンというより.net frameworkのサブセットみたいなものなので、ちょっと正確性にかけた表現ですが。)

Silverlightはランタイムをコンパクトに保つため、機能がないことが多いのですね。
よってDataTriggerもありません。
おしまい。

……ではあまりにひどいので、Silverlightには別バージョンのDataTriggerが用意されています。
名前空間は別の場所にあり、微妙に使い方も違います。


準備

SilverlightでDataTriggerを使うには

Microsoft.Expression.Interactions.dll
System.Windows.Interactivity.dll

が必要です。
この2つはどうやらBlend SDKの最新バージョンに入っているようです。




片道切符

では早速Silverilghtで使ってみます。
次のようなコードになります:
※以前WPFで使った時とは違い、INotifyPropertyChangedの実装が必要なことに注意です。

using System.ComponentModel;

namespace SilverlightDataTriggerDemo
{
    public class MyViewModel:ViewModel
    {
        private bool isViewModelEnabled;
        public bool IsViewModelEnabled
        {
            get { return isViewModelEnabled; }
            set
            {
                isViewModelEnabled = value;
                NotifyPropertyChanged("IsViewModelEnabled");
            }
        }
    }

    public class ViewModel:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        protected void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

XAMLの方はこうです:

<UserControl x:Class="SilverlightDataTriggerDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:SilverlightDataTriggerDemo"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <vm:MyViewModel x:Key="viewModel"/>
    </UserControl.Resources>

    <CheckBox 
        DataContext="{StaticResource viewModel}"
        IsChecked="{Binding IsViewModelEnabled, Mode=TwoWay}">
        <TextBlock>
            <i:Interaction.Triggers>
                <ei:DataTrigger Binding="{Binding IsViewModelEnabled}" Value="true"> 
                    <ei:ChangePropertyAction PropertyName="Text" Value="Changed!!"/>
                </ei:DataTrigger>
            </i:Interaction.Triggers>
        </TextBlock>
    </CheckBox>
</UserControl>




これを実行したSilverlightがこちらです:
(本物です。画像ではありません。操作できます)

上のチェックボックスにチェックを入れてください。
Checked!!と表示されるはずです。
チェックを入れるとビューモデルのIsViewModelEnabledプロパティがtrueになり、それを察知したDataTriggerがテキストを"Checked!!"に変更するのです。

しかし問題もあります。
チェックを一度入れてから外してみてください。
以前のサンプルとは違い、テキストが表示されたままです。

一方通行で、もとに戻らないのです。

可逆変化

元に戻すには、チェックが入っていない状態にテキストを表示させなくさせる操作が、明示的に必要です。(多分)
具体的には、XAMLをこうします:

<UserControl x:Class="SilverlightDataTriggerDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:SilverlightDataTriggerDemo"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <vm:MyViewModel x:Key="viewModel"/>
    </UserControl.Resources>

    <CheckBox 
        DataContext="{StaticResource viewModel}"
        IsChecked="{Binding IsViewModelEnabled, Mode=TwoWay}">
        <TextBlock>
            <i:Interaction.Triggers>
                <ei:DataTrigger Binding="{Binding IsViewModelEnabled}" Value="true"> 
                    <ei:ChangePropertyAction PropertyName="Text" Value="Changed!!"/>
                </ei:DataTrigger>
                <ei:DataTrigger Binding="{Binding IsViewModelEnabled}" Value="false"> 
                    <ei:ChangePropertyAction PropertyName="Text" Value=""/>
                </ei:DataTrigger>
            </i:Interaction.Triggers>
        </TextBlock>
    </CheckBox>
</UserControl>


こうしてできたSilverlightがこれです。
(本物です。画像ではありません。操作してみてください)


どうでしょう!!
今度はチェックを外したら文字が消えます!
意図したとおりの、以前のサンプルと同じ動作です。
・・・・・・しかしそれにしてももう少しスマートな方法はないのでしょうか?
コンバーターを使うという手もありますがなるべくXAMLだけで済ませたいものです・・・


拍手[1回]

PR