与阴影的长方形是在阴影之外的剪报

时间:2016-03-07 15:21:47

标签: c# wpf xaml shapes drawingcontext

继承Shape,我们创建了许多自定义形状。 RectangleAnnotation.cs就是其中之一:

using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Effects;

namespace ShareX.ScreenCaptureLib
{
    public class RectangleAnnotation : Annotation
    {
        public int ShadowSize { get; set; } = 15;

        protected override Geometry DefiningGeometry
        {
            get
            {
                return new RectangleGeometry(new Rect(0, 0, Width, Height));
            }
        }

        public RectangleAnnotation()
        {
            brush = Brushes.Red;

            Fill = Brushes.Transparent;
            Stroke = brush;
            StrokeThickness = 1;

            Effect = new DropShadowEffect
            {
                RenderingBias = RenderingBias.Quality,
                Opacity = 1,
                Color = Colors.Black,
                ShadowDepth = 0,
                BlurRadius = ShadowSize
            };
        }
    }
}

抽象类Annotation.cs如下:

using HelpersLib;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace ShareX.ScreenCaptureLib
{
    public abstract class Annotation : Shape, IAnnotation
    {
        protected Brush brush;
        protected Adorner adorner;

        public bool IsCreating { get; set; }

        private bool selected;

        public bool Selected
        {
            get
            {
                return selected;
            }
            set
            {
                if (Selectable)
                {
                    selected = value;

                    if (selected)
                    {
                        ShowNodes();
                    }
                    else
                    {
                        HideNodes();
                    }
                }
            }
        }

        private bool selectable = true;

        public bool Selectable
        {
            get
            {
                return selectable;
            }
            set
            {
                selectable = value;

                if (!selectable)
                {
                    Selected = false;
                }
            }
        }

        public Point PointStart
        {
            get { return new Point(X1, Y1); }
            set { X1 = value.X; Y1 = value.Y; }
        }

        public Point PointFinish
        {
            get { return new Point(X2, Y2); }
            set { X2 = value.X; Y2 = value.Y; }
        }

        public Rect Bounds
        {
            get
            {
                return CaptureHelper.CreateRectangle(PointStart, PointFinish);
            }
        }

        protected void CreateNodes()
        {
            adorner = new CircleAdorner(this);
            AdornerLayer.GetAdornerLayer(this).Add(adorner);
        }

        protected void ShowNodes()
        {
            if (adorner == null)
            {
                CreateNodes();
            }

            adorner.Visibility = Visibility.Visible;
        }

        protected void HideNodes()
        {
            if (adorner != null)
            {
                adorner.Visibility = Visibility.Hidden;
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);

            if (e.ChangedButton == MouseButton.Left)
            {
                Selected = !Selected;
            }
        }

        public void UpdateDimensions()
        {
            Rect area = Bounds;
            Canvas.SetLeft(this, area.X);
            Canvas.SetTop(this, area.Y);
            Width = area.Width;
            Height = area.Height;
        }

        internal static bool IsDoubleFinite(object o)
        {
            double d = (double)o;
            return (!double.IsInfinity(d) && !double.IsNaN(d));
        }

        public virtual RenderTargetBitmap GetBitmap()
        {
            var rtb = new RenderTargetBitmap((int)Width, (int)Height, AnnotationHelper.CapturedImage.Source.DpiX, AnnotationHelper.CapturedImage.Source.DpiY, PixelFormats.Pbgra32);
            rtb.Render(this);
            return rtb;
        }

        public virtual void Render()
        {
        }

        public static readonly DependencyProperty X1Property = DependencyProperty.Register("X1", typeof(double), typeof(Annotation),
            new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender),
            new ValidateValueCallback(IsDoubleFinite));

        public static readonly DependencyProperty Y1Property = DependencyProperty.Register("Y1", typeof(double), typeof(Annotation),
            new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender),
            new ValidateValueCallback(IsDoubleFinite));

        public static readonly DependencyProperty X2Property = DependencyProperty.Register("X2", typeof(double), typeof(Annotation),
            new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender),
            new ValidateValueCallback(IsDoubleFinite));

        public static readonly DependencyProperty Y2Property = DependencyProperty.Register("Y2", typeof(double), typeof(Annotation),
            new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender),
            new ValidateValueCallback(IsDoubleFinite));

        [TypeConverter(typeof(LengthConverter))]
        public double X1
        {
            get { return (double)GetValue(X1Property); }
            set { SetValue(X1Property, value); }
        }

        [TypeConverter(typeof(LengthConverter))]
        public double Y1
        {
            get { return (double)GetValue(Y1Property); }
            set { SetValue(Y1Property, value); }
        }

        [TypeConverter(typeof(LengthConverter))]
        public double X2
        {
            get { return (double)GetValue(X2Property); }
            set { SetValue(X2Property, value); }
        }

        [TypeConverter(typeof(LengthConverter))]
        public double Y2
        {
            get { return (double)GetValue(Y2Property); }
            set { SetValue(Y2Property, value); }
        }
    }
}

问题在于,当我们在画布中绘制形状时,阴影会被剪切到矩形之外。但是,使用XAML绘制的相同形状会有所不同。

Visual Studio设计器的屏幕截图:

Screenshot from Visual Studio designer

已编译的应用程序窗口的屏幕截图:

Screenshot from compiled app window

我将非常感谢正确指导下的任何帮助。

0 个答案:

没有答案