如何为WPF形状的动画样式添加增量计数器

时间:2014-08-12 02:08:52

标签: c# wpf animation styles

我需要添加一些像计数器一样的东西,并检测形状(矩形)悬停的次数,并相应地稍微改变动画样式。

背景:我有一个单元格网格(矩形),每个单元格都有一个鼠标悬停事件。有两种类型的细胞;单元格类型1是正常单元格,并且必须在悬停时变为绿色,并在鼠标悬停结束时返回其原始透明颜色。类型2单元格是特殊的,在悬停时必须变为绿色,即使鼠标离开矩形也保持不变。

正在使用的代码:

Style PrepareAnimationStyle(int cellType)
        {
            Trigger animTrigger = new Trigger();
            animTrigger.Property = ContentElement.IsMouseOverProperty; 

            System.Windows.Media.Animation.ColorAnimation greenStroke = new System.Windows.Media.Animation.ColorAnimation((Color)ColorConverter.ConvertFromString("#FF66CC00"), TimeSpan.FromSeconds(0));
            //greenStroke.FillBehavior = FillBehavior.HoldEnd;
            System.Windows.Media.Animation.ColorAnimation greenFill = new System.Windows.Media.Animation.ColorAnimation((Color)ColorConverter.ConvertFromString("#FF66CC00"), TimeSpan.FromSeconds(0));
            //greenFill.FillBehavior = FillBehavior.HoldEnd;

            System.Windows.Media.Animation.ColorAnimation transparentFill = new System.Windows.Media.Animation.ColorAnimation(Colors.Transparent, TimeSpan.FromSeconds(1));
            System.Windows.Media.Animation.ColorAnimation silverStroke = new System.Windows.Media.Animation.ColorAnimation(Colors.Silver, TimeSpan.FromSeconds(1));

            System.Windows.Media.Animation.Storyboard sbEnter = new System.Windows.Media.Animation.Storyboard();
            Storyboard.SetTargetProperty(greenStroke, new PropertyPath("Stroke.Color"));
            Storyboard.SetTargetProperty(greenFill, new PropertyPath("Fill.Color"));
            sbEnter.Children.Add(greenStroke);
            sbEnter.Children.Add(greenFill);

            Storyboard sbExit = new Storyboard();
            Storyboard.SetTargetProperty(silverStroke, new PropertyPath("Stroke.Color"));
            Storyboard.SetTargetProperty(transparentFill, new PropertyPath("Fill.Color"));
            sbExit.Children.Add(silverStroke);
            sbExit.Children.Add(transparentFill);

           animTrigger.EnterActions.Add(new BeginStoryboard() { Storyboard = sbEnter });
            if (cellType != 2) //regular cells
                animTrigger.ExitActions.Add(new BeginStoryboard() { Storyboard = sbExit });

            Style cellStyle = new Style();
            cellStyle.Triggers.Add(animTrigger);

            return cellStyle;
        }

问题:如果没有悬停转弯次数的条件,此代码可以正常工作。现在,我很难过如何引入一个可以改变特殊细胞的阴影/不透明度的计数器。我可以制作三种不同的色调 - lightGreen,medGreen,darkGreen并使用它们,或者我可以使用不透明度变量并逐渐增加它;但我不明白我如何使用现有的代码来检查这个计数器的价值是什么以及如何应用必要的输入动画风格。这就是我创建细胞的方式:

grid.Children.Add(new Rectangle()
            {
                Stroke = Brushes.Silver,
                StrokeThickness = 2,
                Fill = Brushes.Transparent,
                Height = cellSize,
                Width = cellSize,
                Style = PrepareAnimationStyle(cellType)
            }); 

有人可以帮我解决这个问题吗?谢谢!

1 个答案:

答案 0 :(得分:1)

我设法使用附加属性来解决它

让我们从rect生成开始

    Rectangle rect = new Rectangle()
    {
        Stroke = new SolidColorBrush(Colors.Silver),
        StrokeThickness = 2,
        Fill = new SolidColorBrush(Colors.Transparent),
        Height = cellSize,
        Width = cellSize,
        Style = (cellType != 2) ? PrepareAnimationStyle(cellType) : null
    };
    if (cellType == 2)
        rect.SetValue(AnimationHelper.IsNonRegularCellProperty, true);
    grid.Children.Add(rect);

请注意,对于工作方法,将颜色值初始化为new SolidColorBrush(Colors...)非常重要,在这种情况下,非常规单元格也不需要样式

我们将附加值为true的属性AnimationHelper.IsNonRegularCellProperty以启用自定义动画。

AnimationHelper类

    class AnimationHelper : DependencyObject
    {
        // Using a DependencyProperty as the backing store for IsNonRegularCell.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsNonRegularCellProperty =
            DependencyProperty.RegisterAttached("IsNonRegularCell", typeof(bool), typeof(AnimationHelper), new PropertyMetadata(false, OnIsNonRegularCellChanged));

        private static void OnIsNonRegularCellChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Rectangle rect = d as Rectangle;
            if ((bool)e.NewValue)
            {
                //to make sure I set the color values again
                rect.Stroke = new SolidColorBrush(Colors.Silver);
                rect.Fill = new SolidColorBrush(Colors.Transparent);
                rect.SetValue(HoverCountProperty, default(byte));
                rect.MouseEnter += rect_MouseEnter;
            }
            else
            {
                rect.MouseEnter -= rect_MouseEnter;
            }
        }

        static void rect_MouseEnter(object sender, MouseEventArgs e)
        {
            Rectangle rect = sender as Rectangle;

            byte hoverCount = (byte)rect.GetValue(HoverCountProperty);
            hoverCount++;
            if (hoverCount > 3)
                return;
            rect.SetValue(HoverCountProperty, hoverCount);
            byte alpha = (byte)(85 * hoverCount);
            ColorAnimation anim = new System.Windows.Media.Animation.ColorAnimation(Color.FromArgb(alpha, 0x66, 0xcc, 0), TimeSpan.FromSeconds(0));
            rect.Fill.BeginAnimation(SolidColorBrush.ColorProperty, anim);
            rect.Stroke.BeginAnimation(SolidColorBrush.ColorProperty, anim);
        }

        // Using a DependencyProperty as the backing store for HoverCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HoverCountProperty =
            DependencyProperty.RegisterAttached("HoverCount", typeof(byte), typeof(AnimationHelper), new PropertyMetadata(default(byte)));
    }

上面的动画将动画为每次增加alpha值增加33%的颜色,以便在3次鼠标悬停中达到100%。