Отслеживание щелчков мыши при отображении плавающей линии - PullRequest
0 голосов
/ 24 января 2019

Пытался найти хороший способ сказать это ... Итак, мой код сбрасывает путевую точку на навигационной карте при двойном щелчке. После того, как первая путевая точка будет удалена, я хочу создать линию между путевой точкой и положением курсора мыши. Кажется, это работает, но после того, как нарисована линия, я больше не могу взаимодействовать с картой или сбрасывать любые другие путевые точки. События двойного щелчка не запускаются, так как кажется, что поток постоянно перерисовывает строку в 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); 

Насколько я понимаю, мне нужно отобразить строку под элементом управления, где она все еще видна, но не мешает мне взаимодействовать с пользовательским интерфейсом. Я не эксперт по WPF, но я не могу придумать другой способ отобразить линию, которая следует за мышью, кроме как запускать событие MouseMove снова и снова. Есть ли лучший способ?

1 Ответ

0 голосов
/ 25 января 2019

Один из способов решить эту проблему - установить для 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>

А затем в классе основного окна:

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;
    }

}
...