当绑定的属性“快速”更改时,我无法使用 DataTriggers 在 WPF 中制作动画。动画是一个元素的简单闪烁。我的问题是,即使在互联网上搜索了很长时间后,我也无法找到一种方法来解释为什么在连续两行中切换属性打开和关闭不起作用,但如果线程休眠 1 毫秒,它就会起作用。我尝试插入其他指令来“浪费”一些时间,但它也不起作用。
这是视图模型中相关的属性:
private bool m_activateFlash;
public bool ActivateFlash
{
get { return m_activateFlash; }
set
{
SetPropertyBackingField(ref m_activateFlash, value);
}
}
Run Code Online (Sandbox Code Playgroud)
这是 XAML:
<DataTemplate x:Key="JobTemplate" DataType="viewModel:JobViewModel">
<Border Margin="8,4,8,4" BorderThickness="1" BorderBrush="{StaticResource BorderBrush}" Background="{StaticResource JobBackgroundBrush}">
<Border.Resources>
<Storyboard x:Key="Blink">
<ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" FillBehavior="Stop"
Duration="0:0:0.4" To="{StaticResource JobBackgroundFlash}" RepeatBehavior="3x" AutoReverse="True"/>
</Storyboard>
</Border.Resources>
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding ActivateFlash, NotifyOnTargetUpdated=True}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Blink}" Name="BeginBlinkStoryBoard"/>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
[....]
Run Code Online (Sandbox Code Playgroud)
最后,这就是它在视图模型中给我带来问题的地方:
private void TriggerFlash()
{
ActivateFlash = true;
System.Threading.Thread.Sleep(1); // HACK DOESN'T WORK WITHOUT THIS LINE
ActivateFlash = false;
}
Run Code Online (Sandbox Code Playgroud)
我将 EventTriggers 视为可能规避该问题的一种方法,但我认为 DataTrigger 是实现我想要的目标的逻辑方法。非常感谢任何帮助:) 编辑 看来我没有在主线程上调用触发闪存。只需调用 Dispatcher.Invoke(...) 即可解决问题
谢谢
亚当
是的,如果你这样做:
ActiveFlash = true;
ActiveFlash = false;
Run Code Online (Sandbox Code Playgroud)
您不会在屏幕上看到任何内容,因为 UI 位于主线程上,并且在值更改之前它没有时间进行绘制。切换值的速度非常快,以至于您在屏幕上看不到任何内容。
我相信,如果我错了,有人可以纠正我,但我相信 WPF 批处理会在幕后重新绘制以提高性能,所以你只是在踩自己。