Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
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);
            }
        }

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.
Posted
Comments
Kenneth Haugland 9-Aug-12 14:04pm    
OnRender is usually used with animations, besides there are projects here on the site:
http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-1

For an onrender example:
http://www.charlespetzold.com/blog/2008/11/030337.html
Kenneth Haugland 9-Aug-12 14:16pm    
I dont know if it helps you but I asked a simular question on MSDN:
http://social.msdn.microsoft.com/Forums/en-CA/wpf/thread/ae5c6abf-76f2-4c45-ba85-37b615c3142f

They basically said change the code :)

1 solution

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 :

C#
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]; }
    }
 
Share this answer
 
Comments
Kenneth Haugland 10-Aug-12 20:11pm    
Looks much better now :) a 5.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900