1

我正在使用 WPF 的绘图程序中Adorner为 a工作。Line是在代码隐藏中绘制的Line,然后用我的自定义Adorner名称装饰LineAdorner。我已经设法使用 aThumb作为Line. 它可以很好地调整大小。我的问题是我无法移动(拖放)线,该怎么做?

public class ResizingAdorner : Adorner
{
    // Resizing adorner uses Thumbs for visual elements.  
    // The Thumbs have built-in mouse input handling.
    //Thumb topLeft, topRight, bottomLeft, bottomRight;

    private Thumb startThumb;
    private Thumb endThumb;
    private Line selectedLine;
    private Point startPoint;
    private Point endPoint;

    // To store and manage the adorner's visual children.
    VisualCollection visualChildren;
    bool IsControlModeOn = false;
    // 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]; }

    // Initialize the ResizingAdorner.
    public ResizingAdorner(UIElement adornedElement)
        : base(adornedElement)
    {
        visualChildren = new VisualCollection(this);
        selectedLine = AdornedElement as Line;
        startThumb = new Thumb { Cursor = Cursors.Hand, Width = 8, Height = 8, Background = Brushes.Green };
        endThumb = new Thumb { Cursor = Cursors.Hand, Width = 8, Height = 8, Background = Brushes.BlueViolet };
        startThumb.DragDelta += StartDragDelta;
        endThumb.DragDelta += EndDragDelta;

        startThumb.DragCompleted += new DragCompletedEventHandler(startThumb_DragCompleted);
        endThumb.DragCompleted += new DragCompletedEventHandler(endThumb_DragCompleted);

        visualChildren.Add(startThumb);
        visualChildren.Add(endThumb);
    }


    public event EndDragDeltaEvent endDragDeltaEvent;
    public delegate void EndDragDeltaEvent(object obj, DragCompletedEventArgs e, bool isEnd);

    void startThumb_DragCompleted(object sender, DragCompletedEventArgs e)
    {
        if (endDragDeltaEvent != null)
            endDragDeltaEvent(selectedLine, e, false);
    }

    void endThumb_DragCompleted(object sender, DragCompletedEventArgs e)
    {
        if (endDragDeltaEvent != null)
            endDragDeltaEvent(selectedLine, e, true);
    }

    // Arrange the Adorners.
    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;
    }

    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 void OnRender(DrawingContext drawingContext)
    {
        if (AdornedElement is Line)
        {
            selectedLine = AdornedElement as Line;
            startPoint = new Point(selectedLine.X1, selectedLine.Y1);
            endPoint = new Point(selectedLine.X2, selectedLine.Y2);
        }
    }
}
4

1 回答 1

0

您需要在线上处理 MouseDown、MouseMove 和 MouseUp 事件才能做到这一点:

在构造函数中为这些事件添加处理程序

selectedLine.MouseLeftButtonDown += SelectedLineOnMouseLeftButtonDown;
selectedLine.MouseMove += SelectedLineOnMouseMove;
selectedLine.MouseLeftButtonUp += SelectedLineOnMouseLeftButtonUp;

实现是这样的

private Point origin;

private void SelectedLineOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{
    e.Handled = true;

    Line line = (Line) sender;
    line.CaptureMouse();

    startPoint = new Point(line.X1, line.Y1);
    endPoint = new Point(line.X2, line.Y2);

    origin = e.GetPosition(line);

    base.OnMouseLeftButtonDown(e);
}

private void SelectedLineOnMouseMove(object sender, MouseEventArgs e) 
{
    base.OnMouseMove(e);
    Line line = (Line) sender;
    if (e.MouseDevice.LeftButton == MouseButtonState.Pressed) 
    {
        Point position = e.GetPosition(this);
        e.Handled = true;
        double horizontalDelta = position.X - origin.X;
        double verticalDelta = position.Y - origin.Y;

        line.X1 = startPoint.X + horizontalDelta;
        line.X2 = endPoint.X + horizontalDelta;
        line.Y1 = startPoint.Y + verticalDelta;
        line.Y2 = endPoint.Y + verticalDelta;

        InvalidateArrange();
    }
    else 
    {
        line.ReleaseMouseCapture();
    }
}

private void SelectedLineOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
{
    Line line = (Line) sender;
    line.ReleaseMouseCapture();
    e.Handled = true;

    base.OnMouseLeftButtonUp(e);
}

我还在 StartDragDelta 和 EndDragDelta 处理程序中添加了一些 InvalidateArrange() 调用,以确保拇指在被拖动时移动。

于 2014-01-23T12:35:06.003 回答