尝试对 Path StrokeProperty 进行动画处理会引发无效操作异常

发布于 2025-01-14 15:08:25 字数 2556 浏览 5 评论 0原文

我有代码,当达到某个值时,我想将路径的描边闪烁为红色。当我尝试像这样应用动画时,它显示 "''System.Windows.Media.Animation.DoubleAnimation' 动画对象无法用于对属性“Stroke”进行动画处理,因为它的类型不兼容“System.Windows”。 Media.Brush'.'" 我也尝试了 ColorAnimation,但仍然出现类似的异常。

在 xaml 的 ControlTemplate 中,我的 Path 定义如下:

<ControlTemplate x:Key="FlaskProgressBarTemplate" TargetType="{x:Type local:FlaskProgressBar}">
<Grid>
<Path x:Name="Outline"
      StrokeThickness="8"
      Stroke="Black">
          <Path.Data>
                <PathGeometry Figures="M 20,15 L 20,60 0,110 60,110 40,60 40,15 Z"/>
          </Path.Data>
  </Path>
</Grid>

在某些方法执行后面的代码中:

private Path _contentPath;
  public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _contentPath = this.GetTemplateChild("Outline") as Path;

            SetValue(this, Value);
        }

     private static void SetValue(FlaskProgressBar instance, double value)
            {
                if (instance._content != null)
                {
                    var rect = instance._content.Rect;
                    instance._content.Rect = new Rect(rect.X, rect.Height - value, rect.Width, rect.Height);
                    if (value == 100)
                    {
                        AnimateBorder(instance); //Error in this method.
                    }
                }
            }
    
      private static void AnimateBorder(FlaskProgressBar instance)
            {
                var path = instance._contentPath;
                if (path != null)
                {
                    path.Stroke = new SolidColorBrush(Colors.Red);
                    var switchOnAnimation = new DoubleAnimation
                    {
                        To = 1,
                        Duration = TimeSpan.Zero,
                        BeginTime = TimeSpan.FromSeconds(0.5)
                    };
    
                    var blinkStoryboard = new Storyboard
                    {
                        Duration = TimeSpan.FromSeconds(1),
                        RepeatBehavior = RepeatBehavior.Forever
                    };
                    Storyboard.SetTarget(switchOnAnimation, path);
                    Storyboard.SetTargetProperty(switchOnAnimation, new PropertyPath(Path.StrokeProperty));
                    blinkStoryboard.Children.Add(switchOnAnimation);
    
                    path.BeginStoryboard(blinkStoryboard); //I get an exception on this line.
                }
            }

I have code when a certain value is reached, I want to flash the Stroke of the Path to Red. When I try to apply the animation like this, it says "''System.Windows.Media.Animation.DoubleAnimation' animation object cannot be used to animate property 'Stroke' because it is of incompatible type 'System.Windows.Media.Brush'.'" I also tried ColorAnimation and still a similar exception.

In the ControlTemplate of xaml I have Path defined as follows:

<ControlTemplate x:Key="FlaskProgressBarTemplate" TargetType="{x:Type local:FlaskProgressBar}">
<Grid>
<Path x:Name="Outline"
      StrokeThickness="8"
      Stroke="Black">
          <Path.Data>
                <PathGeometry Figures="M 20,15 L 20,60 0,110 60,110 40,60 40,15 Z"/>
          </Path.Data>
  </Path>
</Grid>

In the code behind on some method execution:

private Path _contentPath;
  public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _contentPath = this.GetTemplateChild("Outline") as Path;

            SetValue(this, Value);
        }

     private static void SetValue(FlaskProgressBar instance, double value)
            {
                if (instance._content != null)
                {
                    var rect = instance._content.Rect;
                    instance._content.Rect = new Rect(rect.X, rect.Height - value, rect.Width, rect.Height);
                    if (value == 100)
                    {
                        AnimateBorder(instance); //Error in this method.
                    }
                }
            }
    
      private static void AnimateBorder(FlaskProgressBar instance)
            {
                var path = instance._contentPath;
                if (path != null)
                {
                    path.Stroke = new SolidColorBrush(Colors.Red);
                    var switchOnAnimation = new DoubleAnimation
                    {
                        To = 1,
                        Duration = TimeSpan.Zero,
                        BeginTime = TimeSpan.FromSeconds(0.5)
                    };
    
                    var blinkStoryboard = new Storyboard
                    {
                        Duration = TimeSpan.FromSeconds(1),
                        RepeatBehavior = RepeatBehavior.Forever
                    };
                    Storyboard.SetTarget(switchOnAnimation, path);
                    Storyboard.SetTargetProperty(switchOnAnimation, new PropertyPath(Path.StrokeProperty));
                    blinkStoryboard.Children.Add(switchOnAnimation);
    
                    path.BeginStoryboard(blinkStoryboard); //I get an exception on this line.
                }
            }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烟织青萝梦 2025-01-21 15:08:25

您可以通过对画笔的 Opacity 属性(其类型为 Double)而不是画笔本身进行动画处理来实现闪烁效果。

这是我的 BlinkingBorder 类中的样式,在最近的博客文章中出现。

<Style TargetType="{x:Type vctrl:perBlinkingBorder}">
    <Style.Triggers>
        <Trigger Property="IsBlinking" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard TargetProperty="(BlinkingBorderBrush).Opacity">
                        <DoubleAnimation
                            AutoReverse="True"
                            RepeatBehavior="Forever"
                            From="1"
                            To="0"
                            Duration="0:0:0.5">
                            <DoubleAnimation.EasingFunction>
                                <SineEase EasingMode="EaseInOut" />
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
        </Trigger>
    </Style.Triggers>
</Style>

You can achieve a blinking effect by animating the brush's Opacity property (which is of type Double) rather than the brush itself.

This is the style from my BlinkingBorder class that featured in a recent blog post.

<Style TargetType="{x:Type vctrl:perBlinkingBorder}">
    <Style.Triggers>
        <Trigger Property="IsBlinking" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard TargetProperty="(BlinkingBorderBrush).Opacity">
                        <DoubleAnimation
                            AutoReverse="True"
                            RepeatBehavior="Forever"
                            From="1"
                            To="0"
                            Duration="0:0:0.5">
                            <DoubleAnimation.EasingFunction>
                                <SineEase EasingMode="EaseInOut" />
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
        </Trigger>
    </Style.Triggers>
</Style>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文