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

如何在WPF中绘制几何体中的dropshadow效果,wpf,canvas,drawing,shape,Wpf,Canvas,Drawing,Shape,我正在画布中绘制以下形状 当通过更改其颜色(简单部分)并在其周围绘制一个小光环来选择它时,我想将其高亮显示 这就是我使用SASS的方式: 我怎样才能画WPF?请记住,我是使用该方法绘制的。无论您的触发器是什么,您的控件都会进入高亮显示的状态,在该触发器中,只需设置效果属性。对于我的测试,“触发器”是一个属性: public static readonly DependencyProperty ShowShadowProperty = DependencyProperty

我正在
画布中绘制以下
形状

当通过更改其颜色(简单部分)并在其周围绘制一个小光环来选择它时,我想将其高亮显示

这就是我使用SASS的方式:


我怎样才能画WPF?请记住,我是使用该方法绘制的。

无论您的触发器是什么,您的控件都会进入
高亮显示的
状态,在该触发器中,只需设置
效果
属性。对于我的测试,“触发器”是一个属性:

    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
中执行任何操作

  • 在构造函数中设置一些默认值

  • 其中一个默认值是
    Shape.Effect
    ,因为它将在
    MouseEnter
    事件中设置动画

  • 为正常和鼠标移动场景构建
    VisualStates

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

  • 可以使用DPs公开各种属性以进行自定义

    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" />