Синхронизация событий мыши в WPF

321
25 ноября 2017, 07:53

Я хочу, чтобы у меня объекты в Canvas двигались при нажатие мыши и перемещение по горизонтали. Всё получается отлично, кроме того, что если я не двигаю мышь и отпускаю левую кнопку, всё успешно, но если я двигаю мышь и в этот момент отпускаю, бывает не срабатывает MouseUp событие. Как можно это исправить? Приоритет событий что ли. Но надо, чтобы все расчеты в событии MouseMove заканчивались, если вызывается событие MouseUp.

Answer 1

Не использовать MouseUp. Достаточно в MouseMove проверять наличие нажатия клавиши.

    private void MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
             // Тут ваш код движения.
        }
    }
Answer 2

Я как то писал законченный пример для перетаскивания элементов на канвасе. У меня перетаскивается по 2 координатам, но вы можете просто удалить изменения по вертикали и оставить только по горизонтали

class MyWnd : Window
{       
    public MyWnd()
    {
        var c = new Canvas();
        c.Background = new SolidColorBrush(Colors.White);
        var rect = new Rectangle 
                   { 
                     Fill = new SolidColorBrush(Colors.Red), 
                     Width = 20, Height = 20 
                    };
        c.Children.Add(rect);
        this.Content = c;
        Canvas.SetLeft(rect, 0);
        Canvas.SetTop(rect, 0);
        rect.MouseLeftButtonDown+=Handle_MouseDown;
        rect.MouseLeftButtonUp+=Handle_MouseUp;
        rect.MouseMove+=Handle_MouseMove;
    }

    bool isMouseCaptured;
    double mouseVerticalPosition;
    double mouseHorizontalPosition;
    public void Handle_MouseDown(object sender, MouseEventArgs args)
    {
        var item = sender as FrameworkElement;
        mouseVerticalPosition = args.GetPosition(null).Y;
        mouseHorizontalPosition = args.GetPosition(null).X;
        isMouseCaptured = true;
        item.CaptureMouse();
    }
    public void Handle_MouseMove(object sender, MouseEventArgs args)
    {
        var item = sender as FrameworkElement;
        if (isMouseCaptured)
        {
            // Calculate the current position of the object.
            double deltaV = args.GetPosition(null).Y - mouseVerticalPosition;
            double deltaH = args.GetPosition(null).X - mouseHorizontalPosition;
            double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
            double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);
            // Set new position of object.
            item.SetValue(Canvas.TopProperty, newTop);
            item.SetValue(Canvas.LeftProperty, newLeft);
            // Update position global variables.
            mouseVerticalPosition = args.GetPosition(null).Y;
            mouseHorizontalPosition = args.GetPosition(null).X;
        }
    }
    public void Handle_MouseUp(object sender, MouseEventArgs args)
    {
        var item = sender as FrameworkElement;
        isMouseCaptured = false;
        item.ReleaseMouseCapture();
        mouseVerticalPosition = -1;
        mouseHorizontalPosition = -1;
    }
}
void Main()
{
    var wnd = new MyWnd();
    wnd.ShowDialog();
}

А по поводу Capture, что вам советовали - это у меня в строчке item.CaptureMouse();

READ ALSO
Как можно упростить данный код?

Как можно упростить данный код?

Как можно упростить данный код на js?

287
Блокировка вызова js из Console

Блокировка вызова js из Console

Здравствуйте, насмотревшись на Facebok решил блокировать вызов js функций из консоли: на данный момент я вывожу заглушку об использовании консоли...

280
Как передать большой массив через props в vue.js?

Как передать большой массив через props в vue.js?

У меня в родительском компоненте хранится большой массив - несколько сотен элементовЯ через пропс передаю его в дочерний компонент

304