Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize more than one different shape at same time using .net adorner

I am developing a desktop application in WPF, that contains different types of shapes (like circle, radius circle, diameter circle). Now I need to resize shapes on demand so I used .Net adorner which provides the flexibility to drag and resize the shapes. The exact issue is that I want to resize two elements at same time (i.e *When I resize the circle, the radius Line should also resize with respect to the radius start and end points).

Note I haven't tried anything (I have not done any development yet, so I have not code).

Updated Trial of your code. This is a Diameter Circle So when I am drag it it will drag only the ellipse

enter image description here

public class SimpleCircleAdorner : Adorner
    {
        // Be sure to call the base class constructor.
        public SimpleCircleAdorner(UIElement adornedElement, Panel ownerPanel)
            : base(adornedElement)
        {
            _ownerPanel = ownerPanel;
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            Point point = Mouse.GetPosition(AdornedElement);
            _currentPosition = getMousePosition(point);
            switch (_currentPosition)
            {
                case MousePosition.BR:
                case MousePosition.TL:
                    Cursor = Cursors.SizeNWSE;
                    break;
                case MousePosition.BL:
                case MousePosition.TR:
                    Cursor = Cursors.SizeNESW;
                    break;
            }
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(AdornedElement);
            if (adornerLayer != null)
            {
                Adorner[] adorners = adornerLayer.GetAdorners(AdornedElement);
                if (adorners != null)
                {
                    foreach (Adorner adorner in adorners)
                    {
                        adornerLayer.Remove(adorner);
                    }
                }
            }
        }

        MousePosition _currentPosition;
        Panel _ownerPanel;
        bool _isDraging = false;
        Point _startPosition;

        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (Mouse.Capture(this))
            {
                _isDraging = true;
                _startPosition = Mouse.GetPosition(_ownerPanel);
            }
        }

        protected override void OnPreviewMouseMove(MouseEventArgs e)
        {
            if (_isDraging)
            {
                Point newPosition = Mouse.GetPosition(_ownerPanel);
                double diffX = (newPosition.X - _startPosition.X);
                double diffY = (newPosition.Y - _startPosition.Y);

                // we should decide whether to change Width and Height or to change Canvas.Left and Canvas.Right
                if (Math.Abs(diffX) >= 1 || Math.Abs(diffY) >= 1)
                {
                    switch (_currentPosition)
                    {
                        case MousePosition.TL:
                        case MousePosition.BL:
                            foreach (FrameworkElement ui in _ownerPanel.Children)
                            {
                                if (ui.GetType() == typeof(Ellipse) || ui.GetType() == typeof(Line))
                                {
                                    Canvas.SetLeft(ui, Math.Max(0, Canvas.GetLeft(ui) + diffX));
                                    ui.Width = Math.Max(0, ui.Width - diffX);
                                }
                            }
                            _ownerPanel.InvalidateArrange();

                            break;
                        case MousePosition.BR:
                        case MousePosition.TR:

                            foreach (FrameworkElement ui in _ownerPanel.Children)
                            {
                                if (ui.GetType() == typeof(Ellipse) || ui.GetType() == typeof(Line))
                                {
                                    ui.Width = Math.Max(0, ui.Width + diffX);
                                }
                            }
                            break;
                    }


                    switch (_currentPosition)
                    {
                        case MousePosition.TL:
                        case MousePosition.TR:
                            foreach (FrameworkElement ui in _ownerPanel.Children)
                            {
                                if (ui.GetType() == typeof(Ellipse) || ui.GetType() == typeof(Line))
                                {
                                    Canvas.SetTop(ui, Math.Max(0, Canvas.GetTop(ui) + diffY));
                                }
                            }
                            foreach (FrameworkElement ui in _ownerPanel.Children)
                            {
                                if (ui.GetType() == typeof(Ellipse) || ui.GetType() == typeof(Line))
                                {
                                    ui.Height = Math.Max(0, ui.Height - diffY);
                                }
                            }
                            break;
                        case MousePosition.BL:
                        case MousePosition.BR:
                            foreach (FrameworkElement ui in _ownerPanel.Children)
                            {
                                if (ui.GetType() == typeof(Ellipse) || ui.GetType() == typeof(Line))
                                {
                                    ui.Height = Math.Max(0, ui.Height + diffY);
                                }
                            }
                            break;

                    }
                }
                _startPosition = newPosition;
            }
        }

        protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
        {

        }

        protected override void OnPreviewMouseRightButtonUp(MouseButtonEventArgs e)
        {
            if (_isDraging)
            {
                Mouse.Capture(null);
                _isDraging = false;
            }
        }

        MousePosition getMousePosition(Point point) // point relative to element
        {
            double h2 = ActualHeight / 2;
            double w2 = ActualWidth / 2;
            if (point.X < w2 && point.Y < h2)
                return MousePosition.TL;
            else if (point.X > w2 && point.Y > h2)
                return MousePosition.BR;
            else if (point.X > w2 && point.Y < h2)
                return MousePosition.TR;
            else
                return MousePosition.BL;



        }

        enum MousePosition
        {
            TL,
            TR,
            BL,
            BR
        }

        double _renderRadius = 5.0;
        protected override void OnRender(DrawingContext drawingContext)
        {
            Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
            SolidColorBrush renderBrush = new SolidColorBrush(Colors.Black);
            renderBrush.Opacity = 0.3;
            Pen renderPen = new Pen(new SolidColorBrush(Colors.Black), 1.5);
            drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, _renderRadius, _renderRadius);
            drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, _renderRadius, _renderRadius);
            drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, _renderRadius, _renderRadius);
            drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, _renderRadius, _renderRadius);
        }
    }
like image 516
Soni Vimalkumar Avatar asked Feb 16 '17 07:02

Soni Vimalkumar


2 Answers

Assume that there is this MyShapes class, derived from Canvas with some arbitrary Shapes:

public class MyShapes : Canvas
{
    public MyShapes()
    {
        Background = Brushes.Transparent; // for mouse events to fire as expected.

        Ellipse elip = new Ellipse() { Fill = Brushes.Red, Width=40, Height=40 };
        SetLeft(elip, 50);
        SetTop(elip, 10);
        Children.Add(elip);
        elip.MouseEnter += E_MouseEnter;

        Ellipse elip2 = new Ellipse() { Fill = Brushes.Gray, Width = 40, Height = 40 };
        SetLeft(elip2, 600);
        SetTop(elip2, 400);
        Children.Add(elip2);
        elip2.MouseEnter += E_MouseEnter;

        Rectangle rect = new Rectangle() { Fill = Brushes.Blue, Width = 40, Height = 40 };
        SetLeft(rect, 260);
        SetTop(rect, 260);
        Children.Add(rect);
        rect.MouseEnter += E_MouseEnter;

        Rectangle rect2 = new Rectangle() { Fill = Brushes.Yellow, Width = 40, Height = 40 };
        SetLeft(rect2, 400);
        SetTop(rect2, 100);
        Children.Add(rect2);
        rect2.MouseEnter += E_MouseEnter;

    }


    private void E_MouseEnter(object sender, MouseEventArgs e)
    {
        SimpleCircleAdorner ad = new SimpleCircleAdorner((UIElement)sender, this); 
        AdornerLayer adLayer = AdornerLayer.GetAdornerLayer((UIElement)sender);
        adLayer.Add(ad);
    } 

}

I added 4 different Shapes just as an example, you can add more.

Each Shape of this class must handle the MouseEnter event and adds a Custom adorner using AdornerLayer.GetAdornerLayer() method. I used the msdn example:

public class SimpleCircleAdorner : Adorner
{
    // Be sure to call the base class constructor.
    public SimpleCircleAdorner(UIElement adornedElement, Panel ownerPanel)
      : base(adornedElement)
    {
        _ownerPanel = ownerPanel; 
    }

    protected override void OnMouseEnter(MouseEventArgs e)
    {
        Point point = Mouse.GetPosition(AdornedElement);
        _currentPosition = getMousePosition(point);
        switch (_currentPosition)
        {
            case MousePosition.BR:
            case MousePosition.TL:
                Cursor = Cursors.SizeNWSE;
                break;
            case MousePosition.BL:
            case MousePosition.TR:
                Cursor = Cursors.SizeNESW;
                break;
        }
    }

    protected override void OnMouseLeave(MouseEventArgs e)
    { 
        AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(AdornedElement);
        if (adornerLayer != null)
        {
            Adorner[] adorners = adornerLayer.GetAdorners(AdornedElement);
            if (adorners != null)
            {
                foreach (Adorner adorner in adorners)
                { 
                    adornerLayer.Remove(adorner);
                }
            }
        }
    }

    MousePosition _currentPosition;
    Panel _ownerPanel;
    bool _isDraging = false;
    Point _startPosition;

    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        if (Mouse.Capture(this))
        {
            _isDraging = true;
            _startPosition = Mouse.GetPosition(_ownerPanel);
        }
    }

    protected override void OnPreviewMouseMove(MouseEventArgs e)
    {
        if (_isDraging)
        {
            Point newPosition = Mouse.GetPosition(_ownerPanel);
            double diffX = (newPosition.X - _startPosition.X);
            double diffY = (newPosition.Y - _startPosition.Y);

            // we should decide whether to change Width and Height or to change Canvas.Left and Canvas.Right
            if (Math.Abs(diffX) >= 1 || Math.Abs(diffY) >= 1)
            { 
                switch (_currentPosition)
                {
                    case MousePosition.TL:
                    case MousePosition.BL:
                        foreach (FrameworkElement ui in _ownerPanel.Children)
                        { 
                            Canvas.SetLeft(ui, Math.Max(0, Canvas.GetLeft(ui) + diffX)); 
                            ui.Width = Math.Max(0, ui.Width - diffX);
                        }
                        _ownerPanel.InvalidateArrange();

                        break;
                    case MousePosition.BR:
                    case MousePosition.TR:
                        foreach (FrameworkElement ui in _ownerPanel.Children)
                            ui.Width = Math.Max(0, ui.Width + diffX);
                        break;
                }


                switch (_currentPosition)
                {
                    case MousePosition.TL:
                    case MousePosition.TR:
                        foreach (FrameworkElement ui in _ownerPanel.Children)
                            Canvas.SetTop(ui, Math.Max(0, Canvas.GetTop(ui) + diffY));
                        foreach (FrameworkElement ui in _ownerPanel.Children)
                            ui.Height = Math.Max(0, ui.Height - diffY);
                        break;
                    case MousePosition.BL:
                    case MousePosition.BR: 
                        foreach (FrameworkElement ui in _ownerPanel.Children)
                            ui.Height = Math.Max(0, ui.Height + diffY);
                        break;

                }
            }
            _startPosition = newPosition;
        }
    }

    protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        if (_isDraging)
        {
            Mouse.Capture(null);
            _isDraging = false;
        }
    }

    MousePosition getMousePosition(Point point) // point relative to element
    {
        double h2 = ActualHeight / 2;
        double w2 = ActualWidth / 2;
        if (point.X < w2 && point.Y < h2)
            return MousePosition.TL;
        else if (point.X > w2 && point.Y > h2)
            return MousePosition.BR;
        else if (point.X > w2 && point.Y < h2)
            return MousePosition.TR;
        else
            return MousePosition.BL;



    }

    enum MousePosition
    {
        TL,
        TR,
        BL,
        BR
    }

    double _renderRadius = 5.0;

    protected override void OnRender(DrawingContext drawingContext)
    {
        Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize); 
        SolidColorBrush renderBrush = new SolidColorBrush(Colors.Black);
        renderBrush.Opacity = 0.3;
        Pen renderPen = new Pen(new SolidColorBrush(Colors.Black), 1.5); 
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, _renderRadius, _renderRadius);
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, _renderRadius, _renderRadius);
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, _renderRadius, _renderRadius);
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, _renderRadius, _renderRadius);
    }
}

As you can see, apart from the required parts explained in msdn link I provided (such as OnRender() and etc.), you should change some other things too.

First, send the instance of the Canvas in the constructor, because we are going to change the size of its Children. Second, you should handle different mouse events.

Handle MouseEnter event to set the Cursor to a proper Shape. See method getMousePosition(...).

Handle MouseLeave event to remove adorners from the AdornerElement

Handle PreviewMouseLeftButtonDown to set the start of the Dragging.

Handle PreviewMouseLeftButtonUp to set the end of the Dragging.

Handle PreviewMouseMove to determine the new Size and Position of the Elements. This part might be a little tricky, because you should change the Width and Height of the Shapes is some cases, change the Canvas.Left and Canvas.Top properties on some others, and both in the rest.

Result of an example

like image 141
Ron Avatar answered Oct 05 '22 23:10

Ron


I did following for Diameter circle and Radius circle to solve my issue.

public class ResizingAdorner : Adorner
    {
        // Resizing adorner uses Thumbs for visual elements.  
        // The Thumbs have built-in mouse input handling.

        System.Windows.Controls.Primitives.Thumb topLeft, topRight, bottomLeft, bottomRight, Left, Right, RightCenter, Center;

        string m_strelement_prefix = string.Empty;
        List<UIElement> multiObject = new List<UIElement>();
        List<Point> contextData = new List<Point>();
        Panel _ownerPanel;

        // To store and manage the adorner's visual children.
        VisualCollection visualChildren;

        public ResizingAdorner(UIElement adornedElement, Panel ownerPanel)
            : base(adornedElement)
        {
            _ownerPanel = ownerPanel;
            visualChildren = new VisualCollection(this);

            m_strelement_prefix = (adornedElement.Uid != "") ? adornedElement.Uid.Substring(0, 2) : string.Empty;
            if (m_strelement_prefix == string.Empty) { return; }

            switch (m_strelement_prefix)
            {
                case "DC":
                    if (adornedElement.GetType() == typeof(Line) || adornedElement.GetType() == typeof(Ellipse))
                    {
                        BuildAdornerCorner(ref Left, Cursors.Hand);
                        BuildAdornerCorner(ref Right, Cursors.Hand);
                        Left.DragDelta += new DragDeltaEventHandler(onDragDeltaLeft);
                        Right.DragDelta += new DragDeltaEventHandler(onDragDeltaRight);

                        foreach (UIElement ui in _ownerPanel.Children)
                            if (ui.Uid.Contains(m_strelement_prefix)) { multiObject.Add(ui); }
                    }
                    break;
                case "RC":
                    if (adornedElement.GetType() == typeof(Line) || adornedElement.GetType() == typeof(Ellipse))
                    {
                        BuildAdornerCorner(ref Right, Cursors.Hand);
                        Right.DragDelta += new DragDeltaEventHandler(onDragDeltaRight);
                        foreach (UIElement ui in _ownerPanel.Children)
                            if (ui.Uid.Contains(m_strelement_prefix)) { multiObject.Add(ui); }
                    }
                    break;
                case "TC":
                    break;

            }
        }

        void onDragDeltaLeft(object sender, DragDeltaEventArgs args)
        {
            FrameworkElement adornedElement = AdornedElement as FrameworkElement;
            System.Windows.Controls.Primitives.Thumb hitThumb = sender as System.Windows.Controls.Primitives.Thumb;
            if (adornedElement == null || hitThumb == null) return;
            Point position = Mouse.GetPosition(this);

            double distance = 0;
            Point _startPoint = new Point();

            switch (m_strelement_prefix)
            {
                #region Diameter Circle
                case "DC":  
                foreach (UIElement ui in multiObject)
                {
                    if (ui.GetType() != AdornedElement.GetType())
                    {
                        switch (ui.GetType().ToString())
                        {
                            //Selected Element is Ellipse
                            case "System.Windows.Shapes.Line":
                                _startPoint = new Point();
                                distance = getMidPoint(new Point(((Line)ui).X2, ((Line)ui).Y2), position, out _startPoint, true);

                                ((Line)ui).X2 = position.X;
                                ((Line)ui).Y2 = position.Y;

                                ((Ellipse)adornedElement).Height = ((Ellipse)adornedElement).Width = distance * 2;
                                Canvas.SetLeft(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Left);
                                Canvas.SetTop(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Top);

                                break;
                            //Selected Element is Line
                            case "System.Windows.Shapes.Ellipse":
                                _startPoint = new Point();
                                distance = getMidPoint(new Point(((Line)adornedElement).X2, ((Line)adornedElement).Y2), position, out _startPoint, true);

                                ((Line)adornedElement).X2 = position.X;
                                ((Line)adornedElement).Y2 = position.Y;

                                ((Ellipse)ui).Height = ((Ellipse)ui).Width = distance * 2;
                                Canvas.SetLeft(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Left);
                                Canvas.SetTop(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Top);
                                break;
                        }
                    }
                }
                break;
                #endregion 
            }
        }

        void onDragDeltaRight(object sender, DragDeltaEventArgs args)
        {
            FrameworkElement adornedElement = AdornedElement as FrameworkElement;
            System.Windows.Controls.Primitives.Thumb hitThumb = sender as System.Windows.Controls.Primitives.Thumb;
            if (adornedElement == null || hitThumb == null) return;

            Point position = Mouse.GetPosition(this);
            double distance = 0;
            Point _startPoint = new Point();

            switch (m_strelement_prefix)
            {
                #region Diameter Circle
                case "DC":
                    foreach (UIElement ui in multiObject)
                    {
                        if (ui.GetType() != AdornedElement.GetType())
                        {
                            switch (ui.GetType().ToString())
                            {
                                //Selected Element is Ellipse
                                case "System.Windows.Shapes.Line":
                                    _startPoint = new Point();
                                    distance = getMidPoint(new Point(((Line)ui).X1, ((Line)ui).Y1), position, out _startPoint, true);

                                    ((Line)ui).X2 = position.X;
                                    ((Line)ui).Y2 = position.Y;

                                    ((Ellipse)adornedElement).Height = ((Ellipse)adornedElement).Width = distance * 2;
                                    Canvas.SetLeft(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Left);
                                    Canvas.SetTop(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Top);

                                    break;
                                //Selected Element is Line
                                case "System.Windows.Shapes.Ellipse":
                                    _startPoint = new Point();
                                    distance = getMidPoint(new Point(((Line)adornedElement).X1, ((Line)adornedElement).Y1), position, out _startPoint, true);

                                    ((Line)adornedElement).X2 = position.X;
                                    ((Line)adornedElement).Y2 = position.Y;

                                    ((Ellipse)ui).Height = ((Ellipse)ui).Width = distance * 2;
                                    Canvas.SetLeft(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Left);
                                    Canvas.SetTop(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Top);
                                    break;
                            }
                        }
                    }
                    break;
                #endregion

                #region Radius Circle
                case "RC":
                    foreach (UIElement ui in multiObject)
                    {
                        if (ui.GetType() != AdornedElement.GetType())
                        {
                            switch (ui.GetType().ToString())
                            {
                                //Selected Element is Ellipse
                                case "System.Windows.Shapes.Line":
                                    _startPoint = new Point();

                                    distance = getMidPoint(new Point(((Line)ui).X1, ((Line)ui).Y1), position, out _startPoint, false);

                                    ((Line)ui).X2 = position.X;
                                    ((Line)ui).Y2 = position.Y;

                                    ((Ellipse)adornedElement).Height = ((Ellipse)adornedElement).Width = distance * 2;
                                    Canvas.SetLeft(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Left);
                                    Canvas.SetTop(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Top);

                                    break;
                                //Selected Element is Line
                                case "System.Windows.Shapes.Ellipse":
                                    _startPoint = new Point();
                                    distance = getMidPoint(new Point(((Line)adornedElement).X1, ((Line)adornedElement).Y1), position, out _startPoint, false);

                                    ((Line)adornedElement).X2 = position.X;
                                    ((Line)adornedElement).Y2 = position.Y;

                                    ((Ellipse)ui).Height = ((Ellipse)ui).Width = distance * 2;
                                    Canvas.SetLeft(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Left);
                                    Canvas.SetTop(ui, (new Thickness((_startPoint.X - ((distance * 2) / 2)), (_startPoint.Y - ((distance * 2) / 2)), 0, 0)).Top);
                                    break;
                            }
                        }
                    }
                    break;
                #endregion 
            }
        }

        private static double getMidPoint(Point _start,Point _end,out Point _middle , bool findMidPoint)
        {
            _middle = (findMidPoint) ? new Point(((_start.X + _end.X) / 2), ((_start.Y + _end.Y) / 2)) : _start;
            return getDistanceBetweenTwoPoints(_middle, _end);
        }

        private static double getDistanceBetweenTwoPoints(Point StartPoint, Point EndPoint)
        {
            return Math.Round(Math.Sqrt(Math.Pow((EndPoint.X - StartPoint.X), 2) + Math.Pow((EndPoint.Y - StartPoint.Y), 2)), 2);
        }
        // Arrange the Adorners.
        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 = AdornedElement.DesiredSize.Width;
            double desiredHeight = AdornedElement.DesiredSize.Height;

            // adornerWidth & adornerHeight are used for placement as well.
            double adornerWidth = this.DesiredSize.Width;
            double adornerHeight = this.DesiredSize.Height;

            switch (m_strelement_prefix)
            {
                case "DC":
                    if (AdornedElement.GetType() == typeof(Line) || AdornedElement.GetType() == typeof(Ellipse))
                    {
                        if (AdornedElement.GetType() == typeof(Ellipse)) { contextData = ((List<Point>)((AdornedElement as FrameworkElement).DataContext)); }

                        Line selectedLine = ((AdornedElement.GetType() == typeof(Ellipse)) && contextData.Count != 0)
                            ? new Line() { X1 = contextData[0].X, Y1 = contextData[0].Y, X2 = contextData[1].X, Y2 = contextData[1].Y }
                            : (AdornedElement as Line);

                        double left = Math.Min(selectedLine.X1, selectedLine.X2);
                        double top = Math.Min(selectedLine.Y1, selectedLine.Y2);
                        var startRect = new Rect(selectedLine.X1 - (Left.Width / 2), selectedLine.Y1 - (Left.Width / 2), Left.Width, Left.Height);
                        var endRect = new Rect(selectedLine.X2 - (Right.Width / 2), selectedLine.Y2 - (Right.Height / 2), Right.Width, Right.Height);
                        Left.Arrange(startRect);
                        Right.Arrange(endRect);
                    }
                    break;
                case "RC":
                    if (AdornedElement.GetType() == typeof(Line) || AdornedElement.GetType() == typeof(Ellipse))
                    {
                        if (AdornedElement.GetType() == typeof(Ellipse)) { contextData = ((List<Point>)((AdornedElement as FrameworkElement).DataContext)); }

                        Line selectedLine = ((AdornedElement.GetType() == typeof(Ellipse)) && contextData.Count != 0)
                            ? new Line() { X1 = contextData[0].X, Y1 = contextData[0].Y, X2 = contextData[1].X, Y2 = contextData[1].Y }
                            : (AdornedElement as Line);

                        double top = Math.Min(selectedLine.Y1, selectedLine.Y2);
                        var endRect = new Rect(selectedLine.X2 - (Right.Width / 2), selectedLine.Y2 - (Right.Height / 2), Right.Width, Right.Height);
                        Right.Arrange(endRect);
                    }
                    break;
            }
            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 System.Windows.Controls.Primitives.Thumb cornerThumb, Cursor customizedCursor)
        {
            if (cornerThumb != null) return;

            cornerThumb = new System.Windows.Controls.Primitives.Thumb();

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

            visualChildren.Add(cornerThumb);
        }

        // This method ensures that the Widths and Heights are initialized.  Sizing to content produces
        // Width and Height values of Double.NaN.  Because this Adorner explicitly resizes, the Width and Height
        // need to be set first.  It also sets the maximum size of the adorned element.
        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;
            }
        }

        // Override the VisualChildrenCount and GetVisualChild properties to interface with 
        // the adorner's visual collection.
        protected override int VisualChildrenCount { get { return visualChildren.Count; } }
        protected override Visual GetVisualChild(int index) { return visualChildren[index]; }

    }    

enter image description here

enter image description here

like image 24
Soni Vimalkumar Avatar answered Oct 06 '22 00:10

Soni Vimalkumar