当填充/背景颜色发生变化时,WPF会闪烁

本文关键字:WPF 闪烁 变化 填充 背景 颜色 | 更新日期: 2023-09-27 18:27:31

每当数据绑定填充颜色发生变化时,我都希望有一个椭圆填充"闪烁"(立即变白,然后返回到新颜色)。这就是我目前所得到的:

<ctrls:NotifyEllipse Fill="{Binding Cluster.Brush, Converter={StaticResource CloneConverter}}" Width="10" Height="10" >
  <ctrls:NotifyEllipse.Style>
    <Style TargetType="{x:Type ctrls:NotifyEllipse}">
      <Style.Triggers>
        <EventTrigger RoutedEvent="ctrls:NotifyEllipse.FillChanged">
          <BeginStoryboard>
            <Storyboard AutoReverse="True">
              <ColorAnimation Storyboard.TargetProperty="(ctrls:NotifyEllipse.Fill).Color" To="White" Duration="0:0:1" />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Style.Triggers>
    </Style>
  </ctrls:NotifyEllipse.Style>
</ctrls:NotifyEllipse>

其中ctrls:NotifyEllipse是仅包含椭圆的UserControl,具有依赖属性Fill和路由事件FillChanged——类似于这个答案。颜色变化的检测部分工作得很好,但闪光部分(显然)并没有像我希望的那样工作:它首先将填充颜色更改为新颜色,然后慢慢变白,最后又变回新颜色。如上所述,目标是"闪光"——立即变白,然后恢复到新的颜色
请注意,Fill上有数据绑定,所以不可能有两个动画,一个是即时动画,另一个是慢速动画,因为我不知道返回哪种颜色:

<Storyboard>
    <ColorAnimation Storyboard.TargetProperty="(ctrls:NotifyEllipse.Fill).Color" To="White" Duration="0:0:0" />
    <ColorAnimation Storyboard.TargetProperty="(ctrls:NotifyEllipse.Fill).Color" To="???" Duration="0:0:1" />
</Storyboard>

加分:不是立即但快速地闪烁到白色,并保持原始颜色,直到达到全白色,然后慢慢地从白色变为新颜色,这将是理想的解决方案,但我担心这需要大量自定义动画代码。如上所述的闪光就足够了。

当填充/背景颜色发生变化时,WPF会闪烁

只需从White:启动ColorAnimation

<Storyboard>
    <ColorAnimation Storyboard.TargetProperty="Fill.Color"
                    From="White" Duration="0:0:1" />
</Storyboard>

为了完整起见,我的NotifyEllipse类如下所示:

public class NotifyEllipse : Shape
{
    static NotifyEllipse()
    {
        FillProperty.AddOwner(typeof(NotifyEllipse), new FrameworkPropertyMetadata(
            (o, e) =>
            {
                if (e.NewValue != e.OldValue)
                {
                    ((NotifyEllipse)o).RaiseEvent(new RoutedEventArgs(FillChangedEvent));
                }
            }));
    }
    public static readonly RoutedEvent FillChangedEvent =
        EventManager.RegisterRoutedEvent(
            "FillChanged", RoutingStrategy.Bubble,
            typeof(RoutedEventHandler), typeof(NotifyEllipse));
    public event RoutedEventHandler FillChanged
    {
        add { AddHandler(FillChangedEvent, value); }
        remove { RemoveHandler(FillChangedEvent, value); }
    }
    protected override Geometry DefiningGeometry
    {
        get { return new EllipseGeometry(new Rect(RenderSize)); }
    }
}