如何在 WPF 自定义装饰器中用线条排列拇指

Posted

技术标签:

【中文标题】如何在 WPF 自定义装饰器中用线条排列拇指【英文标题】:How to arrange Thumbs with a Line in a WPF custom Adorner 【发布时间】:2012-05-30 17:48:50 【问题描述】:

我正在使用 WPF 在绘图程序中为线条制作装饰器。这条线是在代码隐藏中绘制的,然后用我称为LineAdorner 的自定义 Adorner 进行装饰。我设法使用Thumb 作为线的起点和终点。我的问题是关于起点和终点的拇指排列。我认为问题出在方法ArrangeOverride 中,应该在哪里安排带有起点和终点的拇指。我在Rect XY 参数中找不到合适的减法或加法。我怎样才能找到这些值以始终将拇指与线的点排列在一起? 我的自定义装饰器的代码是这样的:

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;

【问题讨论】:

【参考方案1】:

在您的 ArrangeOverride 中试试这个。您可以去掉“开始”和“结束”变量,并且不需要覆盖 OnRender,因为如果您告诉 Thumb 需要在哪里,它们就会呈现自己。

    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 的宽度和高度减去一半以使端点居中。

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

【讨论】:

完美运行,感谢您的帮助,这正是我想要的。

以上是关于如何在 WPF 自定义装饰器中用线条排列拇指的主要内容,如果未能解决你的问题,请参考以下文章

如何在 WPF 中为装饰器设置 Z 顺序索引

在深度嵌套的视觉树中拖放装饰器

我啥时候应该使用装饰器?

如何在其他一切之上绘制 WPF 装饰器?

如何将自定义装饰器添加到 FastAPI 路由?

如何通过自定义装饰器提供非夹具 pytest 参数?