none
DataTrigger & EventTrigger RRS feed

  • 質問

  • DataTemplateのトリガの定義で、あるデータの値が条件を満たし(DataTrigger)、かつ、マウスがButton上にある(EventTrigger)場合に、Storyboaardが起動する。

    このようなことを、XAMLで記述したいのですが、わかりません。

     

    2010年4月4日 20:56

回答

  • >MultiTrigger クラスを上手く使えばできるかもしれません。

    MultiDataTrigger です。
    http://msdn.microsoft.com/ja-jp/library/ms602960(v=VS.90).aspx

    <Window x:Class="WpfApplication2.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300" Background="Azure">
      <Window.Resources>
        <DataTemplate x:Key="itemvisual">
          <TextBlock Name="textBlock1" Text="{Binding Path=Text}" HorizontalAlignment="Stretch">
            <TextBlock.Background>
              <SolidColorBrush x:Name="itemcolor" Color="White"/>
            </TextBlock.Background>
          </TextBlock>
          <DataTemplate.Triggers>
            <MultiDataTrigger>
              <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Path=IsOK}" Value="True"/>
                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},
                      Path=IsMouseOver}" Value="True"/>
              </MultiDataTrigger.Conditions>
              <MultiDataTrigger.EnterActions>
                <BeginStoryboard>
                  <Storyboard>
                    <ColorAnimation Storyboard.TargetName="itemcolor" Storyboard.TargetProperty="Color" From="White" To="Blue" Duration="0:0:1" />
    
                  </Storyboard>
                </BeginStoryboard>
              </MultiDataTrigger.EnterActions>
              <MultiDataTrigger.ExitActions>
                <BeginStoryboard>
                  <Storyboard>
                    <ColorAnimation Storyboard.TargetName="itemcolor" Storyboard.TargetProperty="Color" From="White" To="White" Duration="0:0:0" />
    
                  </Storyboard>
                </BeginStoryboard>
              </MultiDataTrigger.ExitActions>
            </MultiDataTrigger>
          </DataTemplate.Triggers>
        </DataTemplate>
      </Window.Resources>
        <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ListBox Background="White" Name="listBox1" Opacity="0.9" ItemsSource="{Binding Path=Strings}" ItemTemplate="{StaticResource itemvisual}">
        </ListBox>
        <CheckBox Grid.Row="1" Margin="84,61,74,54" Name="checkBox1" IsChecked="{Binding Path=IsOK}">IsOK</CheckBox>
      </Grid>
    </Window>
    

    プログラムはこんな感じ。

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Windows;
    
    namespace WpfApplication2
    {
        /// <summary>
        /// Window1.xaml の相互作用ロジック
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
                this.DataContext = new Data();
            }
        }
        public class Data : INotifyPropertyChanged
        {
            public Data()
            {
                strings.Add(new Box() { Text = "AA" });
                strings.Add(new Box() { Text = "BB" });
                strings.Add(new Box() { Text = "CC" });
                strings.Add(new Box() { Text = "DD" });
                strings.Add(new Box() { Text = "WW" });
            }
    
            private bool isOK;
            public bool IsOK 
            {
                get
                {
                    return isOK;
                }
                set
                {
                    if (isOK != value)
                    {
                        isOK = value;
                        foreach (Box box in strings) box.IsOK = value;
                        NotifyPropertyChanged("IsOK");
                    }
                }
            }
    
            private ObservableCollection<Box> strings = new ObservableCollection<Box>();
            public ObservableCollection<Box> Strings
            {
                get
                {
                    return strings;
                }
            }
    
            #region INotifyPropertyChanged メンバ
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string name)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }
            #endregion
        }
        public class Box : INotifyPropertyChanged
        {
            public string Text{ get; set; }
            private bool isOK;
            public bool IsOK
            {
                get
                {
                    return isOK;
                }
                set
                {
                    if (isOK != value)
                    {
                        isOK = value;
                        NotifyPropertyChanged("IsOK");
                    }
                }
            }
    
            #region INotifyPropertyChanged メンバ
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string name)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }
            #endregion
        }
    }
    

    えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2010/12
    • 回答としてマーク 遊戯三昧 2010年4月5日 18:37
    2010年4月5日 12:15

すべての返信

  • MultiTrigger クラスを上手く使えばできるかもしれません。

    http://msdn.microsoft.com/ja-jp/library/system.windows.multitrigger(VS.80).aspx

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    2010年4月4日 22:04
  • >MultiTrigger クラスを上手く使えばできるかもしれません。

    MultiDataTrigger です。
    http://msdn.microsoft.com/ja-jp/library/ms602960(v=VS.90).aspx

    <Window x:Class="WpfApplication2.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300" Background="Azure">
      <Window.Resources>
        <DataTemplate x:Key="itemvisual">
          <TextBlock Name="textBlock1" Text="{Binding Path=Text}" HorizontalAlignment="Stretch">
            <TextBlock.Background>
              <SolidColorBrush x:Name="itemcolor" Color="White"/>
            </TextBlock.Background>
          </TextBlock>
          <DataTemplate.Triggers>
            <MultiDataTrigger>
              <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Path=IsOK}" Value="True"/>
                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},
                      Path=IsMouseOver}" Value="True"/>
              </MultiDataTrigger.Conditions>
              <MultiDataTrigger.EnterActions>
                <BeginStoryboard>
                  <Storyboard>
                    <ColorAnimation Storyboard.TargetName="itemcolor" Storyboard.TargetProperty="Color" From="White" To="Blue" Duration="0:0:1" />
    
                  </Storyboard>
                </BeginStoryboard>
              </MultiDataTrigger.EnterActions>
              <MultiDataTrigger.ExitActions>
                <BeginStoryboard>
                  <Storyboard>
                    <ColorAnimation Storyboard.TargetName="itemcolor" Storyboard.TargetProperty="Color" From="White" To="White" Duration="0:0:0" />
    
                  </Storyboard>
                </BeginStoryboard>
              </MultiDataTrigger.ExitActions>
            </MultiDataTrigger>
          </DataTemplate.Triggers>
        </DataTemplate>
      </Window.Resources>
        <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ListBox Background="White" Name="listBox1" Opacity="0.9" ItemsSource="{Binding Path=Strings}" ItemTemplate="{StaticResource itemvisual}">
        </ListBox>
        <CheckBox Grid.Row="1" Margin="84,61,74,54" Name="checkBox1" IsChecked="{Binding Path=IsOK}">IsOK</CheckBox>
      </Grid>
    </Window>
    

    プログラムはこんな感じ。

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Windows;
    
    namespace WpfApplication2
    {
        /// <summary>
        /// Window1.xaml の相互作用ロジック
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
                this.DataContext = new Data();
            }
        }
        public class Data : INotifyPropertyChanged
        {
            public Data()
            {
                strings.Add(new Box() { Text = "AA" });
                strings.Add(new Box() { Text = "BB" });
                strings.Add(new Box() { Text = "CC" });
                strings.Add(new Box() { Text = "DD" });
                strings.Add(new Box() { Text = "WW" });
            }
    
            private bool isOK;
            public bool IsOK 
            {
                get
                {
                    return isOK;
                }
                set
                {
                    if (isOK != value)
                    {
                        isOK = value;
                        foreach (Box box in strings) box.IsOK = value;
                        NotifyPropertyChanged("IsOK");
                    }
                }
            }
    
            private ObservableCollection<Box> strings = new ObservableCollection<Box>();
            public ObservableCollection<Box> Strings
            {
                get
                {
                    return strings;
                }
            }
    
            #region INotifyPropertyChanged メンバ
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string name)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }
            #endregion
        }
        public class Box : INotifyPropertyChanged
        {
            public string Text{ get; set; }
            private bool isOK;
            public bool IsOK
            {
                get
                {
                    return isOK;
                }
                set
                {
                    if (isOK != value)
                    {
                        isOK = value;
                        NotifyPropertyChanged("IsOK");
                    }
                }
            }
    
            #region INotifyPropertyChanged メンバ
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string name)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }
            #endregion
        }
    }
    

    えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2010/12
    • 回答としてマーク 遊戯三昧 2010年4月5日 18:37
    2010年4月5日 12:15
  • MultiDataTriggerの条件に、EventTriggerをもってこれないので、困っていました。

    MouseEnterを条件としたEventTriggerを使わずに、IsMouseOverを条件としたDataTriggerをもってくれば、良いわけですね。

    ありがとうございました。早速、やってみます。

     

    2010年4月5日 18:44