Winform - определить, покинула ли мышь пользовательский элемент управления - PullRequest
4 голосов
/ 08 января 2009

Я борюсь с чем-то, что, по моему мнению, должно быть легко (иш). У меня есть окно формы и панель FlowGridLayout в нижней части формы. Внутри этой формы я динамически заполняю ее числом X пользовательских элементов управления. Все элементы управления одного типа.

Цель - когда пользователь наводит указатель мыши на элемент управления, он открывает другую форму и размещает ее там, где находится мышь. Когда мышь покидает форму, открытая форма исчезает.

Это почти прекрасно работает. Проблема в том, что в пользовательском элементе управления есть что-то вроде метки или текстового поля. Считается, что он покинул UC, поэтому форма исчезает.

Тогда я подумал об использовании X и Y, чтобы определить, находится ли он внутри UC, но я не могу понять это.

Могу я спросить:

1) Каков наилучший подход к этому? 2) Как я могу кодировать это, поскольку UC динамические, я не могу точно знать, где они будут.

Спасибо

EDIT

Я пытаюсь выяснить указатели мыши, но не добираюсь туда. Код ниже находится внутри события 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 Ширина = 62 Высота = 29} System.Drawing.Rectangle

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

Ответы [ 4 ]

4 голосов
/ 08 января 2009

Перехват всех элементов управления 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();
    }
  }
0 голосов
/ 08 января 2009

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

0 голосов
/ 08 января 2009

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

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

0 голосов
/ 08 января 2009

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

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

...