我正在使用 WPF 在绘图程序中为线条制作装饰器。这条线是在代码隐藏中绘制的,然后用我名为 LineAdorner
的自定义 Adorner 进行装饰。我设法使用 Thumb
作为直线的起点和终点。我的问题是拇指关于起点和终点的安排。我认为问题出在方法 ArrangeOverride
中,该方法应该用起点和终点排列 Thumbs。我找不到要在 Rect
X
和 Y
参数中减去或添加的正确数量。我如何找到这些值以始终将 Thumbs 与 Line 的点一起排列?
我的自定义 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,因为如果您告诉 Thumbs 它们需要位于何处,它们就会自行呈现。
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 中进行维护。此外,您需要减去 Thumbs 的宽度和高度的一半,以端点为中心。
由于 Canvas 和 Shapes 的性质,您需要减去线的“真实”left 和 top 值,因为与 Line 不同,装饰器不会从 Canvas 的左上角绘制自己.在使用 Canvasses 之外不需要这样做。
关于c# - 如何在 WPF 自定义 Adorner 中用线条排列 Thumbs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10821556/