Custom Adorner的OnRender中的WPF笔颜色问题 [英] WPF pen color problem in OnRender of Custom Adorner

查看:93
本文介绍了Custom Adorner的OnRender中的WPF笔颜色问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义装饰器,其中我重写了OnRender方法.
还是有点脏,有一些未使用的变量,但是不用管那些;-)

I have a custom adorner where I have overriden the OnRender method.
It''s a bit dirty still, some unused variables but never mind those ;-)

protected override void OnRender(DrawingContext drawingContext)
        {
            if (dragging)
            {
                Rect adornedElementRect = new Rect(0, 0, ActualWidth, ActualHeight);

                //renderBrush.Opacity = 0.2;
                Pen renderPen = new Pen(new SolidColorBrush(Color.FromRgb(147,27,27)), 1);
                //renderPen.Thickness = 0.5;
                
                // Draw topright size marker
                Point p1 = adornedElementRect.TopRight;
                Point p2 = adornedElementRect.TopRight;
                p2.Offset(0, -5);
                drawingContext.DrawLine(renderPen, p1, p2);
                p2.Offset(5, 5);
                drawingContext.DrawLine(renderPen, p1, p2);
                p1.Offset(10, 0);
                p2.Offset(30, 0);
                drawingContext.DrawLine(renderPen, p1, p2);
                Point p3 = p2;

                // Draw bottomright size marker
                p1 = adornedElementRect.BottomRight;
                p2 = adornedElementRect.BottomRight;
                p2.Offset(0, 5);
                drawingContext.DrawLine(renderPen, p1, p2);
                p2.Offset(5, -5);
                drawingContext.DrawLine(renderPen, p1, p2);
                p1.Offset(10, 0);
                p2.Offset(30, 0);
                drawingContext.DrawLine(renderPen, p1, p2);
                p3.Offset(-5, 0);
                p2.Offset(-5, 0);
                drawingContext.DrawLine(renderPen, p3, p2); //the big line
                //draw the text with the height indication
                p1.Offset(-10, 10);
                p2.Offset(-30,30);
                drawingContext.DrawLine(renderPen, p1, p2);
                p3 = p2;

                // Draw bottomleft size marker
                p1 = adornedElementRect.BottomLeft;
                p2 = adornedElementRect.BottomLeft;
                p2.Offset(0, 5);
                drawingContext.DrawLine(renderPen, p1, p2);
                p2.Offset(-5, -5);
                drawingContext.DrawLine(renderPen, p1, p2);
                p1.Offset(0, 10);
                p2.Offset(5, 30);
                drawingContext.DrawLine(renderPen, p1, p2);
            }
        }


我正在使用此装饰器来装饰画布上的某些元素.
这些元素的笔划高度为1,与我在这里的笔相同.
但是无论我用我的装饰笔画什么,它看起来都比我装饰的元素的笔粗.如果我要创建一支较细的笔(例如0.5左右),那么颜色会受到影响.认为0.1是最好的结果,但是颜色影响太大.
有人可以解释这种行为.使用google毫无用处,可能是错误的搜索规范.


I am using this adorner to adorn some elements on a canvas.
These elements have a strokethikness of 1, same as my pen here.
But whatever I draw with my adorner pen it appears thicker than the pen of the element I adorned. If I were to create a thinner pen, say 0.5 or so, then the color is influenced. A thinkness of 0.1 is the best result, but the color is too much influenced.
Can someone explain this behaviour. Used google to no avail, maybe wrong search specification.

推荐答案

通过创建自定义控件并将其实例化为装饰子元素来解决它,就像Microsoft所做的那样.他们的例子中的拇指.
然后,自定义控件将以常规方式简单地创建所有形状和内容,而不会遇到我之前遇到的问题.
这是代码:

Solved it by creating a custom control and instantiating it as child of the adorner some way as microsoft did it with the thumbs in their example.
The custom control then simply creates all the shapes and stuff in the normal way and does not suffer from the problems I faced before.
Here''s the code :

public class ResizeableSelectionAdorner : Adorner
    {
        Thumb topLeft, topRight, bottomLeft, bottomRight;
        DrawingSizeIndicator drawingSizeIndicator;
        VisualCollection visualChildren;

        public ResizeableSelectionAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            visualChildren = new VisualCollection(this);

            // Call a helper method to initialize the Thumbs
            // with a customized cursors.
            BuildAdornerCorner(ref topLeft, Cursors.SizeNWSE);
            BuildAdornerCorner(ref topRight, Cursors.SizeNESW);
            BuildAdornerCorner(ref bottomLeft, Cursors.SizeNESW);
            BuildAdornerCorner(ref bottomRight, Cursors.SizeNWSE);

            bottomLeft.DragDelta += new DragDeltaEventHandler(HandleBottomLeft);
            bottomRight.DragDelta += new DragDeltaEventHandler(HandleBottomRight);
            topLeft.DragDelta += new DragDeltaEventHandler(HandleTopLeft);
            topRight.DragDelta += new DragDeltaEventHandler(HandleTopRight);

            bottomLeft.GotMouseCapture += new MouseEventHandler(Corner_GotMouseCapture);
            bottomRight.GotMouseCapture += new MouseEventHandler(Corner_GotMouseCapture);
            topLeft.GotMouseCapture += new MouseEventHandler(Corner_GotMouseCapture);
            topRight.GotMouseCapture += new MouseEventHandler(Corner_GotMouseCapture);

            bottomLeft.LostMouseCapture += new MouseEventHandler(Corner_LostMouseCapture);
            bottomRight.LostMouseCapture += new MouseEventHandler(Corner_LostMouseCapture);
            topLeft.LostMouseCapture += new MouseEventHandler(Corner_LostMouseCapture);
            topRight.LostMouseCapture += new MouseEventHandler(Corner_LostMouseCapture);

            drawingSizeIndicator = new DrawingSizeIndicator();
            drawingSizeIndicator.Opacity = 0;
            visualChildren.Add(drawingSizeIndicator);
        }

        void Corner_LostMouseCapture(object sender, MouseEventArgs e)
        {
            bottomLeft.Opacity = 0.4;
            bottomRight.Opacity = 0.4;
            topLeft.Opacity = 0.4;
            topRight.Opacity = 0.4;
            drawingSizeIndicator.Opacity = 0;
            InvalidateVisual();
        }

        void Corner_GotMouseCapture(object sender, MouseEventArgs e)
        {
            bottomLeft.Opacity = 0;
            bottomRight.Opacity = 0;
            topLeft.Opacity = 0;
            topRight.Opacity = 0;
            drawingSizeIndicator.Opacity = 1;
            InvalidateVisual();
        }

        void HandleBottomRight(object sender, DragDeltaEventArgs args)
        {
            FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
            Thumb hitThumb = sender as Thumb;

            if (adornedElement == null || hitThumb == null) return;
            FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;

            // Ensure that the Width and Height are properly initialized after the resize.
            EnforceSize(adornedElement);

            // Change the size by the amount the user drags the mouse, as long as it's larger 
            // than the width or height of an adorner, respectively.
            adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
            adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
        }

        void HandleBottomLeft(object sender, DragDeltaEventArgs args)
        {
            FrameworkElement adornedElement = AdornedElement as FrameworkElement;
            Thumb hitThumb = sender as Thumb;

            if (adornedElement == null || hitThumb == null) return;

            // Ensure that the Width and Height are properly initialized after the resize.
            EnforceSize(adornedElement);

            // Change the size by the amount the user drags the mouse, as long as it's larger 
            // than the width or height of an adorner, respectively.
            if (adornedElement.Width != Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width))
            {
                double x = Canvas.GetLeft(adornedElement) + args.HorizontalChange;
                Canvas.SetLeft(adornedElement, x);
                adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
            }
            adornedElement.Height = Math.Max(args.VerticalChange + adornedElement.Height, hitThumb.DesiredSize.Height);
        }

        void HandleTopRight(object sender, DragDeltaEventArgs args)
        {
            FrameworkElement adornedElement = this.AdornedElement as FrameworkElement;
            Thumb hitThumb = sender as Thumb;

            if (adornedElement == null || hitThumb == null) return;
            FrameworkElement parentElement = adornedElement.Parent as FrameworkElement;

            // Ensure that the Width and Height are properly initialized after the resize.
            EnforceSize(adornedElement);

            // Change the size by the amount the user drags the mouse, as long as it's larger 
            // than the width or height of an adorner, respectively.
            adornedElement.Width = Math.Max(adornedElement.Width + args.HorizontalChange, hitThumb.DesiredSize.Width);
            double y = Canvas.GetTop(adornedElement) + args.VerticalChange;
            Canvas.SetTop(adornedElement, y);
            adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
        }

        void HandleTopLeft(object sender, DragDeltaEventArgs args)
        {
            FrameworkElement adornedElement = AdornedElement as FrameworkElement;
            Thumb hitThumb = sender as Thumb;

            if (adornedElement == null || hitThumb == null) return;

            // Ensure that the Width and Height are properly initialized after the resize.
            EnforceSize(adornedElement);

            // Change the size by the amount the user drags the mouse, as long as it's larger 
            // than the width or height of an adorner, respectively.
            if (adornedElement.Width != Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width))
            {
                double x = Canvas.GetLeft(adornedElement) + args.HorizontalChange;
                Canvas.SetLeft(adornedElement, x);
                adornedElement.Width = Math.Max(adornedElement.Width - args.HorizontalChange, hitThumb.DesiredSize.Width);
            }

            if (adornedElement.Height != Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height))
            {
                double y = Canvas.GetTop(adornedElement) + args.VerticalChange;
                Canvas.SetTop(adornedElement, y);
                adornedElement.Height = Math.Max(adornedElement.Height - args.VerticalChange, hitThumb.DesiredSize.Height);
            }
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            // desiredWidth and desiredHeight are the width and height of the element that's being adorned.  
            // These will be used to place the ResizingAdorner at the corners of the adorned element.  
            double desiredWidth = ActualWidth;
            double desiredHeight = ActualHeight;
            // adornerWidth & adornerHeight are used for placement as well.
            double adornerWidth = this.DesiredSize.Width;
            double adornerHeight = this.DesiredSize.Height;

            topLeft.Arrange(new Rect(-adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
            topRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, -adornerHeight / 2, adornerWidth, adornerHeight));
            bottomLeft.Arrange(new Rect(-adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));
            bottomRight.Arrange(new Rect(desiredWidth - adornerWidth / 2, desiredHeight - adornerHeight / 2, adornerWidth, adornerHeight));

            drawingSizeIndicator.Arrange(new Rect(-drawingSizeIndicator.ElementIndicatorLength+1,-drawingSizeIndicator.ElementIndicatorLength,
                desiredWidth + drawingSizeIndicator.ElementIndicatorLength * 4 + drawingSizeIndicator.SizeIndicatorLength-2,
                desiredHeight + drawingSizeIndicator.ElementIndicatorLength * 4 + drawingSizeIndicator.SizeIndicatorLength-1));

            // Return the final size.
            return finalSize;
        }

        // Helper method to instantiate the corner Thumbs, set the Cursor property, 
        // set some appearance properties, and add the elements to the visual tree.
        void BuildAdornerCorner(ref Thumb cornerThumb, Cursor customizedCursor)
        {
            if (cornerThumb != null) return;

            cornerThumb = new Thumb();

            // Set some arbitrary visual characteristics.
            cornerThumb.Cursor = customizedCursor;
            cornerThumb.Height = cornerThumb.Width = 10;
            cornerThumb.Opacity = 0.40;
            cornerThumb.Background = new SolidColorBrush(Colors.MediumBlue);

            visualChildren.Add(cornerThumb);
        }

        void EnforceSize(FrameworkElement adornedElement)
        {
            if (adornedElement.Width.Equals(Double.NaN))
                adornedElement.Width = adornedElement.DesiredSize.Width;
            if (adornedElement.Height.Equals(Double.NaN))
                adornedElement.Height = adornedElement.DesiredSize.Height;

            FrameworkElement parent = adornedElement.Parent as FrameworkElement;
            if (parent != null)
            {
                adornedElement.MaxHeight = parent.ActualHeight;
                adornedElement.MaxWidth = parent.ActualWidth;
            }
        }

        protected override int VisualChildrenCount { get { return visualChildren.Count; } }
        protected override Visual GetVisualChild(int index) { return visualChildren[index]; }
    }


这篇关于Custom Adorner的OnRender中的WPF笔颜色问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆