我正在尝试使用WPF动画创建一种效果,当文本属性中的数据发生变化时,文本会淡出,然后再次出现..或者最好是正确的交叉渐变。
我已经成功完成了一半的工作,下面的代码响应文本更改事件,立即使文本不可见,然后在3秒内淡化它。
淡出文本同样简单,我只需更改标记的From和To属性。但是 - 问题是屏幕上的文字立即改变了。当然,这通常是绝对必要的,但在这种情况下,我希望OLD文本淡出,然后新文本淡入。
在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>
答案 0 :(得分:3)
我对此表示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处理程序内的可见性。
希望这有帮助!
答案 1 :(得分: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();
}
}
答案 2 :(得分:1)
此任务的最佳解决方案是使用“Transition Presenter”。 Transition presenter是一个容器,用于控制(可以是TextBlock或其他任何内容),它通过应用指定的转换对内容的更改做出反应。您可以选择一个预定义的过渡或创建自己的过渡(使用XAML)。通常,转换演示者使用数据模板来显示绑定数据。最基本的例子如下:
<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>
以下是两个包含实现转换演示者的源代码的库:
答案 3 :(得分:-1)
我不认为这可能是仅限XAML的解决方案。 TextBlock不知道'旧'和'新'文本,只知道文本。
我这样做的方法是创建一个派生自TextBlock的自定义控件,并在TargetUpdated事件上执行以下操作: