Winform - определяет, вышла ли мышь из-под контроля пользователя
-
05-07-2019 - |
Вопрос
Я борюсь с чем-то, что, по моему мнению, должно быть легко (ish).У меня есть форма Windows и панель flowgridlayout в нижней части формы.Внутри этой формы я динамически заполняю ее X количеством пользовательских элементов управления.Все элементы управления одного типа.
Цель состоит в том, когда пользователь наводит курсор мыши на пользовательский элемент управления, он открывает другую форму и позиционирует ее там, где находится мышь.Когда мышь покидает форму, открытая форма исчезает.
Это почти отлично работает.Проблема заключается в том, что внутри пользовательского элемента управления есть что-то вроде метки или текстового поля.Считается, что он покинул UC, поэтому форма исчезает.
Тогда моей мыслью было использовать X и Y, чтобы определить, находится ли это внутри UC, но я не могу в этом разобраться.
Могу я спросить:
1) Каков наилучший подход к этому?2) Как я могу это закодировать, поскольку UC являются динамическими, я не могу точно знать, где они будут.
Спасибо
Редактировать
Я пытаюсь вычислить указатели мыши, но у меня ничего не получается.Приведенный ниже код находится в событии UC SmallTagBox_MouseLeave:
Point loc = this.Location;
Point p = this.PointToScreen(this.Location);
Point p2 = this.PointToScreen(this.Parent.Location);
Point ms = MousePosition;
Rectangle screenBounds = new Rectangle(this.PointToScreen(this.Location), this.Size);
if (!screenBounds.Contains(ms))
{
thw.Close();
thw = null;
}
- Система loc {X = 275 Y = 3}.Чертеж.Точка
- Система p {X = 808 Y = 908}.Рисунок.Точка
- Система p {X = 808 Y = 908}.Рисунок.Точка
- Система p2 {X = 545 Y = 1542}.Чертеж.Точка
- Система ms {X = 574 Y = 914}.Чертеж.Точка
- Границы экрана {X = 808 Y = 908 Ширина = 62 Высота = 29} Система.Рисунок.Прямоугольник
Я не понимаю, как p2 (его родительский элемент) может иметь большее значение Y относительно экрана.
Решение
Привязать все элементы управления к событиям MouseEnter и MouseLeave, а затем выяснить, находится ли он все еще внутри формы, довольно болезненно.Простой таймер тоже может выполнить эту работу:
public partial class Form1 : Form {
private Timer mTimer;
public Form1() {
InitializeComponent();
mTimer = new Timer();
mTimer.Interval = 200;
mTimer.Tick += mTimer_Tick;
mTimer.Enabled = true;
}
private void mTimer_Tick(object sender, EventArgs e) {
if (!this.DesktopBounds.Contains(Cursor.Position)) this.Close();
}
}
Другие советы
Идея 1) Когда MouseLeave
при срабатывании события вы можете проверить координаты мыши (относительно экрана) и проверить, находятся ли они все еще в пределах вашего пользовательского контроля.Если это так, следует предположить, что мышь должна пройти обратно через элемент управления, чтобы выйти за пределы границ, и на этот раз вы можете спокойно проигнорировать событие.
Идея 2) Прикрепить MouseEnter
обработчики событий для дочерних элементов управления.Затем, когда мышь войдет в один из них, вы будете знать и сможете игнорировать пользовательский элемент управления MouseLeave
событие.Затем, когда ребенок MouseLeave
срабатывает событие, проверьте, нет ли в usercontrol MouseEnter
снова.
Я думаю, я бы добавил обработчик событий для MouseLeave
для каждого элемента управления, который у вас есть и который вы используете Parent
свойство для поиска нужного вам пользовательского элемента управления.Я согласен, хотя это будет немного болезненно.
Вы также можете перебирать все дочерние элементы управления (рекурсивные) в вашем элементе управления, а также присоединять к ним события MouseEnter и MouseLeave.
Вы должны вести некоторую бухгалтерию, если мышь находится под вашим контролем или каким-либо дочерним элементом управления.