События мыши Wpf за пределами проблемы пользовательского элемента управления

У меня странная проблема, я не знаю, как ее исправить.

Я создаю палитру цветов с нуля. Я делаю это, создавая набор пользовательских элементов управления и объединяя их в "главный элемент управления".

Например, когда пользователь перетаскивает средство выбора оттенка, я перемещаю мышь вниз, двигаюсь и вверх (внутри пользовательского элемента управления средства выбора оттенка).

Простой bool диктует, что происходит, насколько фактическое движение идет.

//Mouse down
 _isDrag = true;

//Mouse Move
if(!_isDrag) return; 
//Moving the position indicator shape thingy
//Calculating the hue

//Mouse Up
_isDrag = false;

Но, если наведение мыши происходит за пределами средства выбора оттенка, событие наведения мыши не срабатывает. Таким образом, когда пользователь возвращается в область средства выбора оттенка, индикатор формы фигуры начинает работать быстро.

Я уверен, что ответ лежит где-то, но я боюсь, что мои навыки поиска не соответствуют задаче. Я понятия не имею, что искать.

Спасибо за ваше время.

Решение:

private bool _isDrag;

    //Request Mouse capture for the Container
    private void MsDown(object sender, MouseButtonEventArgs e)
    {
        _isDrag = true;
        Mouse.Capture(MainContainer);
    }

    //Release Mouse capture
    private void MsUp(object sender, MouseButtonEventArgs e)
    {
        _isDrag = false;
        Mouse.Capture(null);
    }

    //Move the handle vertically along the main container, with respect to it's width - so it's centered.
    private void MsMove(object sender, MouseEventArgs e)
    {
        if (!_isDrag) return;
        Canvas.SetTop(Handle, e.GetPosition(ContentRow).Y - Handle.ActualHeight / 2);
    }

Спасибо за ваш ответ!

Изменить 2:

В продолжение моего вопроса. В то время как Capture в основном добилась цели, я заметил, что, если быстро перетаскивать за пределы пользовательского элемента управления, иногда ручка застревает близко к краю. Если бы я медленно двигал мышью, этого бы не случилось. Weird. Кроме того, я никогда не мог достичь 0 и.ActualHeight

Так что я опубликую свое исправление здесь, на случай, если другой чувак столкнется с этой проблемой.

Я разделил свою сетку так:

<Grid.ColumnDefinitions>
        <ColumnDefinition Width="7"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="7"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="7"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="7"></RowDefinition>
    </Grid.RowDefinitions>

7 - половина размера моей ручки (круг).

Область содержимого (фактическая область, с которой вы можете взаимодействовать визуально) находится в средней ячейке (в отдельной сетке с видимостью теста ложного попадания).

Покрытие всей главной сетки - это невидимый прямоугольник, используемый для проверки попадания.

И переместить ручку

        private void MoveHandle()
    {
        _pos.X = _pos.X - Handle.ActualWidth/2;
        _pos.Y = _pos.Y - Handle.ActualHeight / 2;
         //this is just to be sure. I'm paranoid. Being a color picker, these actually matter a lot.
        _pos.X = Math.Max(Math.Min(_pos.X, RectColor.ActualWidth - Handle.ActualWidth/2), -Handle.ActualWidth / 2);
        _pos.Y = Math.Max(Math.Min(_pos.Y, RectColor.ActualHeight -Handle.ActualWidth/2), -Handle.ActualHeight/2);

        Canvas.SetLeft(Handle, _pos.X);
        Canvas.SetTop(Handle, _pos.Y);
    }

Я понятия не имею, почему предыдущий код у меня почти работал. Это в основном то же самое, что и раньше. Но, так или иначе, это работает в миллион раз лучше. Удачи!

1 ответ

Решение

Поисковый термин, который вы ищете - захват мыши. Захват в свой MouseDown, и вы можете получить события мыши, даже когда мышь покидает ваш контроль.

Другие вопросы по тегам