显示浮动线时跟踪鼠标点击

Tracking mouse clicks while displaying a floating line

试图找到一个很好的表达方式。所以,我的代码在双击时在航海图上放置了一个航路点。放下第一个航路点后,我想在航路点和鼠标光标位置之间创建一条线。这似乎是可行的,但在绘制线之后,我无法再与地图进行交互或删除任何其他 waypoints。双击事件不会触发,因为线程似乎不断地在 mouse_move 上重新绘制线条,这是 StackPanel 上的一个事件。

public async void _navigationChartPanel_MouseMove(object sender, MouseEventArgs e)
{
    foreach (var element in _panelChart.Children)
    {
        if (element is Line && ((Line)element).Name == "RangeBearingLine")
        {
            index = _panelChart.Children.IndexOf(element);
            break;
        }
    }

    if (index >= 0)
    {
        _panelChart.Children.RemoveAt(index);
    }

    var line = new Line
    {
        Name = "RangeBearingLine",
        StrokeThickness = 1,
        Stroke = System.Windows.Media.Brushes.Red,
        X1 = _parent._routePlanner.lastWaypointLoc.X,
        Y1 = _parent._routePlanner.lastWaypointLoc.Y,
        X2 = mouseClick.X,
        Y2 = mouseClick.Y
    };

    _panelChart.Children.Add(line); 

据我了解,我需要在控件下方显示该行,该行仍然可见但不妨碍我与 UI 进行交互。我不是 WPF 专家,但除了一遍又一遍地触发 MouseMove 事件之外,我想不出另一种方法来显示鼠标后的线条。有没有更好的方法?

解决此问题的一种方法是在您创建的子元素上将 IsHitTesting 设置为 false。一种更简单的方法是拦截 PreviewMouseDown,因为这是一个隧道事件,因此将在子控件之前为父控件调用:

<Canvas x:Name="theCanvas" Background="CornflowerBlue" PreviewMouseDown="Canvas_MouseDown" PreviewMouseMove="Canvas_MouseMove">
    <Rectangle Canvas.Left="100" Canvas.Top="100" Width="200" Height="200" Fill="Green" /> <!-- to show that it will also work when you click on other children -->
</Canvas>

然后在你的主 window class:

public partial class MainWindow : Window
{
    private Line CurrentLine;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
    {           
        var pos = e.GetPosition(theCanvas);
        if (e.ClickCount == 2)
        {
            this.CurrentLine = new Line
            {
                Name = "RangeBearingLine",
                StrokeThickness = 1,
                Stroke = System.Windows.Media.Brushes.Red,
                X1 = pos.X,
                Y1 = pos.Y,
                X2 = pos.X,
                Y2 = pos.Y
            };
            theCanvas.Children.Add(this.CurrentLine);
            e.Handled = true;
        }
        else if ((e.ClickCount == 1) && (this.CurrentLine != null))
        {
            this.CurrentLine.X2 = pos.X;
            this.CurrentLine.Y2 = pos.Y;
            this.CurrentLine = null;
            e.Handled = true;
        }
    }
    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (this.CurrentLine == null)
            return;
        var pos = e.GetPosition(theCanvas);
        this.CurrentLine.X2 = pos.X;
        this.CurrentLine.Y2 = pos.Y;
        e.Handled = true;
    }

}