سؤال

I'm working on a Adorner for a Line in a drawing program using WPF. The Line is drawn in code-behind and then adorned with my custom Adorner called LineAdorner. I've managed to use a Thumb for the start and end point of the Line. My problem is the arrangement of the Thumbs regarding the start and end points. I think the problem is in the method ArrangeOverride, where is supposed to arrange the Thumbs with the start and end points. I can't find the right amount to subtract or add in the Rect X and Y parameters. How can i find these values to always arrange the Thumbs with the points of the Line? The code from my custom Adorner is this:

public class LineAdorner : Adorner { private Point start; private Point end; private Thumb startThumb; private Thumb endThumb; private Line selectedLine; private VisualCollection visualChildren; // Constructor public LineAdorner(UIElement adornedElement) : base(adornedElement) { visualChildren = new VisualCollection(this); startThumb = new Thumb { Cursor = Cursors.Hand, Width = 10, Height = 10, Background = Brushes.Green }; endThumb = new Thumb { Cursor = Cursors.Hand, Width = 10, Height = 10, Background = Brushes.BlueViolet }; startThumb.DragDelta += StartDragDelta; endThumb.DragDelta += EndDragDelta; visualChildren.Add(startThumb); visualChildren.Add(endThumb); selectedLine = AdornedElement as Line; } // Event for the Thumb Start Point private void StartDragDelta(object sender, DragDeltaEventArgs e) { Point position = Mouse.GetPosition(this); selectedLine.X1 = position.X; selectedLine.Y1 = position.Y; } // Event for the Thumb End Point private void EndDragDelta(object sender, DragDeltaEventArgs e) { Point position = Mouse.GetPosition(this); selectedLine.X2 = position.X; selectedLine.Y2 = position.Y; } protected override int VisualChildrenCount { get { return visualChildren.Count; } } protected override Visual GetVisualChild(int index) { return visualChildren[index]; } protected override void OnRender(DrawingContext drawingContext) { if (AdornedElement is Line) { selectedLine = AdornedElement as Line; start = new Point(selectedLine.X1, selectedLine.Y1); end = new Point(selectedLine.X2, selectedLine.Y2); } } protected override Size ArrangeOverride(Size finalSize) { var startRect = new Rect(selectedLine.X1, selectedLine.Y1, ActualWidth, ActualHeight); startThumb.Arrange(startRect); var endRect = new Rect(selectedLine.X2, selectedLine.Y2, ActualWidth, ActualHeight); endThumb.Arrange(endRect); return finalSize; } }

هل كانت مفيدة؟

المحلول

Try this in your ArrangeOverride. You can get rid of the "start" and "end" variables, and you don't need to override OnRender since your Thumbs will render themselves if you tell them where they need to be.

    protected override Size ArrangeOverride(Size finalSize)
{
    selectedLine = 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 - (startThumb.Width / 2), selectedLine.Y1 - (startThumb.Width / 2), startThumb.Width, startThumb.Height);
    startThumb.Arrange(startRect);

    var endRect = new Rect(selectedLine.X2 - (endThumb.Width / 2), selectedLine.Y2 - (endThumb.Height / 2), endThumb.Width, endThumb.Height);
    endThumb.Arrange(endRect);

    return finalSize;
}

You are setting an explicit size on the Thumbs, so that had to be maintained in the Arrange. Also, you need to subtract half the width and height of the Thumbs to center on the end points.

Due to the nature of the Canvas and Shapes, you need to subtract the "real" left and top values of the line, since unlike the Line, the Adorners are not going to draw themselves from the top-left on the Canvas. This shouldn't be required outside of using Canvasses.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top