WPF - 使动画的执行以绑定数据项的属性为条件

Dre*_*kes 14 wpf animation xaml datatemplate coloranimation

我有一个数据对象 - 一个名为的自定义类Notification- 公开一个IsCritical属性.这个想法是,如果通知到期,它有一段有效期,应该引起用户的注意.

想象一下这个测试数据的场景:

_source = new[] {
    new Notification { Text = "Just thought you should know" },
    new Notification { Text = "Quick, run!", IsCritical = true },
  };
Run Code Online (Sandbox Code Playgroud)

第二项应出现在ItemsControl具有脉冲背景的情况下.这是一个简单的数据模板摘录,显示了我想要动画灰色和黄色背景的方法.

<DataTemplate DataType="Notification">
  <Border CornerRadius="5" Background="#DDD">
    <Border.Triggers>
      <EventTrigger RoutedEvent="Border.Loaded">
        <BeginStoryboard>
          <Storyboard>
            <ColorAnimation 
              Storyboard.TargetProperty="Background.Color"
              From="#DDD" To="#FF0" Duration="0:0:0.7" 
              AutoReverse="True" RepeatBehavior="Forever" />
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>
    </Border.Triggers>
    <ContentPresenter Content="{TemplateBinding Content}" />
  </Border>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

我不确定的是如何使这个动画以值的形式为条件IsCritical.如果绑定值为false,#DDD则应保留默认的背景颜色.

Anv*_*aka 12

这个难题的最后一部分是...... DataTriggers.您所要做的就是将一个DataTrigger添加到您的DataTemplate,将其绑定到IsCritical属性,并且只要它是真的,在它的EnterAction/ExitAction中,您可以开始和停止突出显示故事板.这是完全可行的解决方案,带有一些硬编码的快捷方式(你绝对可以做得更好):

Xaml:

<Window x:Class="WpfTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Notification Sample" Height="300" Width="300">
  <Window.Resources>
    <DataTemplate x:Key="NotificationTemplate">
      <Border Name="brd" Background="Transparent">
        <TextBlock Text="{Binding Text}"/>
      </Border>
      <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsCritical}" Value="True">
          <DataTrigger.EnterActions>
            <BeginStoryboard Name="highlight">
              <Storyboard>
                <ColorAnimation 
                  Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"
                  Storyboard.TargetName="brd"
                  From="#DDD" To="#FF0" Duration="0:0:0.5" 
                  AutoReverse="True" RepeatBehavior="Forever" />
              </Storyboard>
            </BeginStoryboard>
          </DataTrigger.EnterActions>
          <DataTrigger.ExitActions>
            <StopStoryboard BeginStoryboardName="highlight"/>
          </DataTrigger.ExitActions>
        </DataTrigger>
      </DataTemplate.Triggers>
    </DataTemplate>
  </Window.Resources>
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ItemsControl ItemsSource="{Binding Notifications}"
                  ItemTemplate="{StaticResource NotificationTemplate}"/>
    <Button Grid.Row="1"
            Click="ToggleImportance_Click"
            Content="Toggle importance"/>
  </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

代码背后:

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;

namespace WpfTest
{
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();
      DataContext = new NotificationViewModel();
    }

    private void ToggleImportance_Click(object sender, RoutedEventArgs e)
    {
      ((NotificationViewModel)DataContext).ToggleImportance();
    }
  }

  public class NotificationViewModel
  {
    public IList<Notification> Notifications
    {
      get;
      private set;
    }

    public NotificationViewModel()
    {
      Notifications = new List<Notification>
                        {
                          new Notification
                            {
                              Text = "Just thought you should know"
                            },
                          new Notification
                            {
                              Text = "Quick, run!",
                              IsCritical = true
                            },
                        };
    }

    public void ToggleImportance()
    {
      if (Notifications[0].IsCritical)
      {
        Notifications[0].IsCritical = false;
        Notifications[1].IsCritical = true;
      }
      else
      {
        Notifications[0].IsCritical = true;
        Notifications[1].IsCritical = false;
      }
    }
  }

  public class Notification : INotifyPropertyChanged
  {
    private bool _isCritical;

    public string Text { get; set; }

    public bool IsCritical
    {
      get { return _isCritical; }
      set
      {
        _isCritical = value;
        InvokePropertyChanged("IsCritical");
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void InvokePropertyChanged(string name)
    {
      var handler = PropertyChanged;
      if (handler != null)
      {
        handler(this, new PropertyChangedEventArgs(name));
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 :).