c# – 如何在WPF自定义Adorner中使用Line排列Thumb

我正在使用WPF在绘图程序中使用Adorner for Line. Line是在代码隐藏中绘制的,然后使用名为LineAdorner的自定义Adorner进行装饰.我已经设法使用Thumb作为Line的起点和终点.我的问题是Thumbs关于起点和终点的安排.我认为问题在于ArrangeOverride方法,其中应该使用起点和终点来安排Thumbs.我找不到合适的数量来减去或添加Rect X和Y参数.如何找到这些值以始终使用Line的点排列Thumbs?
我的自定义Adorner的代码是这样的:



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;
     }
    }

解决方法:

在ArrangeOverride中尝试这个.您可以摆脱“开始”和“结束”变量,并且您不需要覆盖OnRender,因为如果您告诉他们需要的位置,您的拇指将自我渲染.

    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;
}

您在Thumbs上设置了显式大小,因此必须在Arrange中进行维护.此外,您需要减去拇指的宽度和高度的一半以使端点居中.

由于“画布”和“形状”的性质,您需要减去线条的“实际”左侧和顶部值,因为与“线条”不同,“装饰”不会从“画布”的左上角绘制自己.在使用Canvasses之外不应该这样做.

上一篇:c# – 测量字符串就像在html上一样吗?


下一篇:c# – Graphics.DrawString如何在绘制后删除它(undo-redo)?