События мыши 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, и вы можете получить события мыши, даже когда мышь покидает ваш контроль.