Winform - определить, оставила ли мышь пользовательский контроль

Я борюсь с чем-то, что, как мне кажется, должно быть легко (иш). У меня есть форма окна и панель 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} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p2 {X = 545 Y = 1542} System.Drawing.Point
  • мс {X = 574 Y = 914} System.Drawing.Point
  • screenBounds {X = 808 Y = 908 Width = 62 Height = 29} System.Drawing.Rectangle

Я не понимаю, как p2 (его родитель) может иметь большее значение Y относительно экрана.


person Jon    schedule 08.01.2009    source источник


Ответы (4)


Перехватить все элементы управления событиями 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();
    }
  }
person Hans Passant    schedule 08.01.2009
comment
Привет, nobugz, я думаю, что это сработало бы, если бы мышь находилась внутри всплывающей формы, но указатель мыши находится в пользовательском элементе управления. Форма появляется рядом с ней, но не сверху, поэтому мышь не войдет в эту форму. Поэтому я не верю, что могу использовать DesktopBounds. - person Jon; 09.01.2009
comment
Я пошел на компромисс и поставил таймер на всплывающую форму и позволил ему исчезнуть через X секунд, даже если мышь все еще там. - person Jon; 09.01.2009
comment
Спасибо за это! Отлично работает в моем сценарии! - person Tim Friesen; 09.07.2018

Идея 1) Когда возникает событие MouseLeave, вы можете проверить координаты мыши (относительно экрана) и проверить, находятся ли они по-прежнему в пределах вашего пользовательского контроля. Если это так, следует предположить, что мышь должна пройти обратно через элемент управления, чтобы выйти за границы, и на этот раз вы можете спокойно проигнорировать событие.

Идея 2) Присоедините MouseEnter обработчики событий к дочерним элементам управления. Тогда, когда мышь войдет в один, вы узнаете и сможете проигнорировать событие MouseLeave пользовательского элемента управления. Затем, когда срабатывает дочернее событие MouseLeave, снова проверьте MouseEnter элемента управления.

person lc.    schedule 08.01.2009
comment
Я попробовал это и с треском провалился ... Я уверен, что это возможно, но я не мог заставить свои границы работать. Если бы кто-то мог привести небольшой пример, это было бы великолепно !. Спасибо - person Jon; 08.01.2009

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

person Grzenio    schedule 08.01.2009

Вы также можете перебрать все дочерние элементы управления (рекурсивные) в своем элементе управления и также присоединить к ним события MouseEnter и MouseLeave.

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

person GvS    schedule 08.01.2009