我正在使用WPF在绘图程序中为Adorner
处理Line
。 Line
在代码隐藏中绘制,然后使用名为Adorner
的自定义LineAdorner
进行装饰。我设法使用Thumb
作为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);
}
}
}
答案 0 :(得分:1)
你需要在线上处理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()调用,以确保在拖动时拇指移动。