c# - 如何在 WPF 自定义 Adorner 中用线条排列 Thumbs

标签 c# wpf drawing adorner

我正在使用 WPF 在绘图程序中为线条制作装饰器。这条线是在代码隐藏中绘制的,然后用我名为 LineAdorner 的自定义 Adorner 进行装饰。我设法使用 Thumb 作为直线的起点和终点。我的问题是拇指关于起点和终点的安排。我认为问题出在方法 ArrangeOverride 中,该方法应该用起点和终点排列 Thumbs。我找不到要在 Rect XY 参数中减去或添加的正确数量。我如何找到这些值以始终将 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/

相关文章:

c# - 如果集合值相同,为什么 LongListSelector 会添加额外的项目?

c# - 从PC读取接收到android手机的数据

wpf - RibbonMenuButton 样式和模板

c# - 开关盒的替代品

c# - 从数据网格中删除项目后重置行号

C# 图表适合一个选项卡

opencv - 找出一个圆的所有点

c# - c# 的图形查看器/抽屉?

apache-flex - 弹性 : drawing a connector line between shapes

c# - 如何通过给定的点集合确定形状是半圆?