基于属性更改的WPF动画在启动时触发

时间:2017-11-01 11:26:34

标签: c# wpf wpf-animation

当绑定到文本框的Text属性的值发生更改时,我正在尝试为Border的颜色设置动画:

<Border x:Name="border" BorderThickness="3" BorderBrush="Blue" HorizontalAlignment="Center" VerticalAlignment="Center">
    <TextBlock Background="White" TextAlignment="Center" FontSize="24" 
                       Text="{Binding Value, NotifyOnTargetUpdated=True}">
        <TextBlock.Triggers>
            <EventTrigger RoutedEvent="Binding.TargetUpdated">
                <EventTrigger.Actions>
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation To="Yellow"
                                Storyboard.TargetName="border"
                                AutoReverse="True"
                                Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                                FillBehavior="Stop"
                                Duration="0:0:0.5"
                                RepeatBehavior="5x" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>
        </TextBlock.Triggers>
    </TextBlock>
</Border>

问题是即使应用程序启动并且尚未设置值,也会触发动画。 有没有解决方案来避免这种情况?

1 个答案:

答案 0 :(得分:1)

以下是我建议的解决方法的工作演示。这使用AgentOctal.WpfLib Nuget包(免责声明:我是这个包的作者)用于ViewModel基类和ICommand实现,但是您应该可以轻松地替换任何系统使用

如果我找到更适合您的选项,我会将其作为额外答案添加。

enter image description here

MainWindow.xaml(注意:EventTrigger上的TextBlock已更改为DataTrigger上的Border

<Window
    x:Class="BindingHelp.MainWindow"
    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:local="clr-namespace:BindingHelp"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="525"
    Height="350"
    mc:Ignorable="d">
    <Window.DataContext>
        <local:MainWindowVm />
    </Window.DataContext>
    <StackPanel Orientation="Vertical">
        <Border
            x:Name="border"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            BorderBrush="Blue"
            BorderThickness="3">
            <Border.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=ShouldAnimate}" Value="true">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <ColorAnimation
                                            AutoReverse="True"
                                            FillBehavior="Stop"
                                            RepeatBehavior="5x"
                                            Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                                            To="Yellow"
                                            Duration="0:0:0.5" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Border.Style>
            <TextBlock
                MinWidth="200"
                Background="White"
                FontSize="24"
                Text="{Binding Value, NotifyOnTargetUpdated=True}"
                TextAlignment="Center" />
        </Border>
        <Button Command="{Binding Path=SetValueCommand}" Content="Update Value" />
    </StackPanel>
</Window>

MainWindowVm.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using AgentOctal.WpfLib;
using AgentOctal.WpfLib.Commands;

namespace BindingHelp
{
    class MainWindowVm : ViewModel
    {
        private string _value;
        public string Value
        {
            get { return _value; }
            set
            {
                if (SetValue(ref _value, value))
                {
                    ShouldAnimate = true;
                }
            }
        }

        private bool _shouldAnimate = false;
        public bool ShouldAnimate
        {
            get { return _shouldAnimate; }
            set { SetValue(ref _shouldAnimate, value); }
        }


        private ICommand _setValueCommand;
        public ICommand SetValueCommand
        {
            get
            {
                return _setValueCommand ?? (_setValueCommand = new SimpleCommand((obj) =>
                {
                    Value = "This is a test!";
                }));
            }
        }    
    }
}