如何在WPF中的几何体中绘制阴影效果

时间:2016-10-05 10:44:58

标签: wpf canvas drawing shape

我在Shape中绘制了以下Canvas

我想通过更改颜色(简单部分)和在其周围绘制一个小光环来选择突出显示

enter image description here

这就是我使用SASS的方式:http://codepen.io/aaromnido/pen/zKvAwd/

我如何在WPF中绘制?请记住,我正在使用Shape's OnRender方法进行绘制。

2 个答案:

答案 0 :(得分:1)

无论你的触发器是什么,你的控件进入Highlighted状态,在该触发器中只需设置Effect属性。对于我的测试,"触发"属性:

    public static readonly DependencyProperty ShowShadowProperty =
        DependencyProperty.Register ("ShowShadow", typeof (bool), typeof (TestShape), new PropertyMetadata (false, ShowShadowChanged));

    public bool ShowShadow
    {
        get { return (bool)GetValue (ShowShadowProperty); }
        set { SetValue (ShowShadowProperty, value); }
    }

    private static void ShowShadowChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((TestShape)d).OnShowShadow ();
    }

    private void OnShowShadow ()
    {
        if (ShowShadow)
        {
            Effect = new DropShadowEffect { Direction = 0, ShadowDepth = 20, BlurRadius = 33, Opacity = 1, Color = Colors.Black};
        }
        else
        {
            Effect = null;
        }
    }

这意味着您不需要在OnRender中执行任何操作。

答案 1 :(得分:1)

  1. 在构造函数中设置一些默认值。

  2. 其中一个默认值为Shape.Effect,因为它会在MouseEnter事件中设置动画。

  3. 为Normal和MouseEnter方案构建VisualStates

  4. 使用VisualStateVisualStateManager.GoToElementState()事件处理程序中的MouseEnter更改元素的MouseLeave

  5. 您可以使用DP公开各种属性进行自定义。

    <强> NewShape.cs

    using System.Windows.Shapes;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows;
    using System.Windows.Media.Effects;
    
    namespace WpfStackOverflow.NewShape
    {
        public class CNewShape : Shape
        {
            public CNewShape()
            {
                // setting the defaults
                this.Width = 40;
                this.Height = 40;
                this.Stroke = new SolidColorBrush() { Color = Colors.Red };
                this.StrokeThickness = 5;
                this.Effect = new DropShadowEffect() {
    
                    Color = Colors.Transparent,
                    BlurRadius = 1,
                    Direction = -150,
                    ShadowDepth = 1            
                };
    
                // constructing the VisualStates
                _constructVisualStates();
    
                // event handlers
                this.MouseEnter += CNewShape_MouseEnter;
                this.MouseLeave += CNewShape_MouseLeave;
            }
    
            #region EventHandlers
            void CNewShape_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
            {
                VisualStateManager.GoToElementState(this, "VSNormal", false);
            }
    
            void CNewShape_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
            {
                VisualStateManager.GoToElementState(this, "VSMouseEnter", false);
            }
            #endregion
    
            #region Overrides
    
            // This needs to be implemented as it is abstract in base class
            GeometryGroup geo = new GeometryGroup();
            protected override Geometry DefiningGeometry
            {
                get { return geo; }
            }
    
            protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
            {
                Pen pen = new Pen(this.Stroke, StrokeThickness);
                drawingContext.DrawEllipse(Brushes.Transparent, pen, new Point(Width/2, Height/2), 40, 40);
    
                drawingContext.DrawEllipse(Stroke, null, new Point(Width / 2, Height / 2), 30, 30);
                base.OnRender(drawingContext);
            }
            #endregion
    
            #region Helpers
    
            private void _constructVisualStates()
            {         
                VisualStateGroup vsg1 = new VisualStateGroup();
    
                #region VSNormal (Normal Visual State)
                    VisualState stateVSNormal = new VisualState() { Name = "VSNormal" };
    
                    Storyboard sbVSNormal = new Storyboard();
                        ObjectAnimationUsingKeyFrames oa = new ObjectAnimationUsingKeyFrames();
                        Storyboard.SetTargetProperty(oa, new PropertyPath("Effect"));
                        DiscreteObjectKeyFrame dokf = new DiscreteObjectKeyFrame(null);
                        oa.KeyFrames.Add(dokf);
                        sbVSNormal.Children.Add(oa);
    
                    stateVSNormal.Storyboard = sbVSNormal;
                    vsg1.States.Add(stateVSNormal);
                #endregion                       
    
                #region VSMouseEnter (MouseEnter Visual State)
                    VisualState stateVSMouseEnter = new VisualState() { Name = "VSMouseEnter" };
    
                    Storyboard sbVSMouseEnter = new Storyboard();
    
                        ColorAnimation caStrokeColor = new ColorAnimation();
                        caStrokeColor.To = (Color)ColorConverter.ConvertFromString("#FF24BCDE");
                        Storyboard.SetTargetProperty(caStrokeColor, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)"));
                        sbVSMouseEnter.Children.Add(caStrokeColor);
    
                        ColorAnimation caEffectColor = new ColorAnimation();
                        caEffectColor.To = (Color)ColorConverter.ConvertFromString("#FFA4E1F3");
                        Storyboard.SetTargetProperty(caEffectColor, new PropertyPath("(Shape.Effect).(Color)"));
                        sbVSMouseEnter.Children.Add(caEffectColor);
    
                        DoubleAnimation daBlurRadius = new DoubleAnimation();
                        daBlurRadius.To = 10;
                        Storyboard.SetTargetProperty(daBlurRadius, new PropertyPath("(Shape.Effect).(BlurRadius)"));
                        sbVSMouseEnter.Children.Add(daBlurRadius);
    
                        DoubleAnimation daDirection = new DoubleAnimation();
                        daDirection.To = -190;
                        Storyboard.SetTargetProperty(daDirection, new PropertyPath("(Shape.Effect).(Direction)"));
                        sbVSMouseEnter.Children.Add(daDirection);              
    
                    stateVSMouseEnter.Storyboard = sbVSMouseEnter;
                    vsg1.States.Add(stateVSMouseEnter);
                #endregion
    
                VisualStateManager.GetVisualStateGroups(this).Add(vsg1);
            }
    
            #endregion
        }
    }
    

    <强> 用法

     <local:CNewShape Canvas.Left="70" Canvas.Top="52" Stroke="#FF374095" StrokeThickness="10" Width="100" Height="100" />
    

    <强> 输出

    图像质量差。在屏幕上实际输出看起来不错。

    Animated Button