【问题标题】:WPF animation based on property change triggers at start启动时基于属性更改触发器的 WPF 动画
【发布时间】:2017-11-01 11:26:34
【问题描述】:

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

<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>

问题是即使在应用程序启动并且值尚未设置一次时也会触发动画。 有没有办法避免这种情况?

【问题讨论】:

  • 所有这些都绑定到一个视图模型吗?
  • 您可以在加载 TextBlock 后或首次引发 Binding.TargetUpdated 后以编程方式添加触发器。
  • @BradleyUffner 是的,它是一个实现 INotifyPropertyChanged 的​​简单视图模型
  • 你可以触发你控制的其他东西的动画。我知道这并不理想,但你可以有一个bool 属性来确定动画是否应该播放,触发该属性为true 的动画,然后在@987654325 的设置器中将该属性设置为true @。我正在寻找“更好”的选项,但 WPF 动画是一个我还没有太多经验的领域。

标签: c# wpf wpf-animation


【解决方案1】:

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

如果我为您找到更好的选择,我会将其添加为附加答案。

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

<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!";
                }));
            }
        }    
    }
}

【讨论】:

    猜你喜欢
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 2010-12-18
    • 2013-08-15
    • 1970-01-01
    • 2017-06-24
    相关资源
    最近更新 更多