【问题标题】:WPF Text Fade out-then-in effectWPF 文本淡出后入效果
【发布时间】:2009-08-11 21:22:48
【问题描述】:

我正在尝试使用 WPF 动画来创建一种效果,当文本属性中的数据发生变化时,文本会淡出,然后再次出现......或者最好是适当的淡入淡出。

我已经成功完成了一半的工作,下面的代码响应文本更改事件,立即使文本不可见,然后在 3 秒内将其淡化。

要淡出文本同样简单,我只需更改标签的 From 和 To 属性。但是 - 问题是屏幕上的文字会立即改变。当然,这通常是绝对必需的,但在这种情况下,我希望 OLD 文本淡出,然后 NEW 文本淡入。

在 WPF 动画中这样做有什么巧妙的技巧吗?

当前半完成触发器:

<Style TargetType="TextBlock" x:Key="fadeinout">
        <Style.Triggers>
            <EventTrigger RoutedEvent="Binding.TargetUpdated">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:3" From="0.0" To="1.0" BeginTime="0:0:0" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Style.Triggers>
    </Style>

【问题讨论】:

    标签: wpf text animation


    【解决方案1】:

    我同意frances1983 的意见。我要做的是制作一个新的 UserControl,它实际上可以通过淡入淡出无缝处理新旧文本。

    我正在对一个标签做类似的事情,我只想显示几秒钟然后消失。这是我所做的:

    <Label  Name="lbl" DockPanel.Dock="Bottom" HorizontalAlignment="Center" Visibility="Collapsed">
        <Label.Style>
            <Style TargetType="{x:Type Label}">
                <Style.Triggers>
                    <Trigger Property="Visibility" Value="Visible">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:00" BeginTime="00:00:00" From="0.0" To="1.0" />
                                    <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:03" BeginTime="00:00:02" From="1.0" To="0.0" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Label.Style>
        Display Text
    </Label>
    

    然后在标签文本发生变化的代码中:

    //Make the label visible, starting the storyboard.
    lbl.Visibility = Visibility.Visible;
    
    DispatcherTimer t = new DispatcherTimer();
    //Set the timer interval to the length of the animation.
    t.Interval = new TimeSpan(0, 0, 5);
    t.Tick += (EventHandler)delegate(object snd, EventArgs ea)
    {
        // The animation will be over now, collapse the label.
        lbl.Visibility = Visibility.Collapsed;
        // Get rid of the timer.
        ((DispatcherTimer)snd).Stop();
    };
    t.Start();
    

    您可以轻松地将此示例修改为 UserControl。只需更改 Visibility == Hidden 上的淡出,添加一个对 Visibility == Visible 执行相反操作的情节提要, 并更改文本并重置 Tick 处理程序内的可见性。

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      这是一个自动执行淡出、切换值、淡入的实现

      使用(将 xmlns:l 设置为正确的命名空间后:

      Label l:AnimatedSwitch.Property="Content" l:AnimatedSwitch.Binding="{Binding SomeProp}"/>
      

      代码(这是概念验证代码,没有错误处理,还没有准备好生产)。

      public class AnimatedSwitch : DependencyObject
      {
          // Define the attached properties
      
          public static DependencyProperty BindingProperty =
              DependencyProperty.RegisterAttached("Binding", typeof(object), typeof(AnimatedSwitch),
              new PropertyMetadata(BindingChanged));
          public static DependencyProperty PropertyProperty =
              DependencyProperty.RegisterAttached("Property", typeof(string), typeof(AnimatedSwitch));
          public static object GetBinding(DependencyObject e)
          {
              return e.GetValue(BindingProperty);
          }
          public static void SetBinding(DependencyObject e, object value)
          {
              e.SetValue(BindingProperty, value);
          }
          public static string GetProperty(DependencyObject e)
          {
              return (string)e.GetValue(PropertyProperty);
          }
          public static void SetProperty(DependencyObject e, string value)
          {
              e.SetValue(PropertyProperty, value);
          }
      
          // When the value changes do the fadeout-switch-fadein
      
          private static void BindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              Storyboard fadeout = new Storyboard();
              var fadeoutAnim = new DoubleAnimation(){To=0,Duration=new Duration(TimeSpan.FromSeconds(0.3))};
              Storyboard.SetTarget(fadeoutAnim,d);
              Storyboard.SetTargetProperty(fadeoutAnim, new PropertyPath("Opacity"));
              fadeout.Children.Add(fadeoutAnim);
              fadeout.Completed += (d1, d2) =>
                  {
                      d.GetType().GetProperty(GetProperty(d)).SetValue(d, GetBinding(d), null);
      
                      Storyboard fadein = new Storyboard();
                      var fadeinAnim = new DoubleAnimation() { To = 1, Duration = new Duration(TimeSpan.FromSeconds(0.3)) };
                      Storyboard.SetTarget(fadeinAnim, d);
                      Storyboard.SetTargetProperty(fadeinAnim, new PropertyPath("Opacity"));
                      fadein.Children.Add(fadeinAnim);
                      fadein.Begin();
                  };
              fadeout.Begin();
          }
      }
      

      【讨论】:

        【解决方案3】:

        此任务的最佳解决方案是使用“过渡演示者”。过渡演示者是您的控件(可以是 TextBlock 或其他任何东西)的容器,它通过应用分配的过渡来对内容的更改做出反应。您可以选择一种预定义的转换或创建您自己的转换(使用 XAML)。通常transition Presenter使用数据模板来展示绑定的数据。最基本的示例如下所示:

        <lib:TransitionPresenter Transition="{StaticResource FadeTransition}
            Content="{Binding MyValue}">
            <lib:TransitionPresenter.Resources>
                <DataTemplate DataType="{x:Type System:string}">
                    <TextBlock Text={Binding}/>
                </DataTemplate>
            </lib:TransitionPresenter.Resources>
        </lib:TransitionPresenter>
        

        这里有两个库,其中包含实现过渡演示器的源代码:

        【讨论】:

          【解决方案4】:

          我认为这不可能出现在纯 XAML 解决方案中。 TextBlock 不知道“旧”和“新”文本,只知道文本。

          我这样做的方法是创建一个从 TextBlock 派生的自定义控件,并在 TargetUpdated-event 上执行以下操作:

          • 调用“淡出”故事板
          • 更改文本
          • 调用“淡入”故事板

          祝你好运:)

          【讨论】:

          • 当然可以,只需使用两个文本块
          猜你喜欢
          • 2011-03-05
          • 2011-10-16
          • 1970-01-01
          • 2011-01-01
          • 2014-07-20
          • 1970-01-01
          • 1970-01-01
          • 2021-07-04
          • 2021-11-02
          相关资源
          最近更新 更多