2010-08-02 2 views
5

Я переношу этот вопрос из-за невозможности решить проблему (оригинал here).Событие MouseLeave срабатывает при перемещении по экрану управления ScrollBar

В TreeView, ListBox, или, похоже, из моего поиска Google что-либо с помощью ScrollBar, ScrollBar не считается частью элемента управления.

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

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

Итак, я переместил все на Windows TreeView, но не могу найти способ надежного захвата MouseLeave - только если он покидает весь TreeView, включая полосу прокрутки.

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

Вкратце:

скроллбара не срабатывает MouseEnter или MouseLeave для контроля, и что делает использование MouseEnter/MouseLeave для выскальзывания управления непригодным, так как пользователь не может использовать ScrollBar.

Каков предпочтительный способ обработки этой ситуации?

В предыдущем вопросе мне был дан совет по использованию Spy ++ и попытка подключиться к WndProc() для обработки MouseEnter/MouseLeave для ScrollBar.

Это, однако, не работает, поскольку сообщения, показанные Spy ++, не срабатывали в WndProc() на уровне формы или уровне управления. Это как если бы .NET просто не видел ScrollBar.

Использование WndProc() также представляется нереалистичным для такого простого запроса, есть ли другой способ сделать это, или если WndProc() - единственный способ, смог ли кто-нибудь действительно достичь этого и показать мне, как это сделать?

ответ

4

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

Punt. Как только вы получите MouseEnter, запустите таймер на 200 мс. В событии Tick проверьте, продолжает ли курсор мыши видеть дерево. Например:

private void treeView1_MouseEnter(object sender, EventArgs e) { 
     timer1.Enabled = true; 
     treeView1.Width = 220; 
    } 

    private void timer1_Tick(object sender, EventArgs e) { 
     Point pos = treeView1.PointToClient(Cursor.Position); 
     if (!treeView1.DisplayRectangle.Contains(pos)) { 
      timer1.Enabled = false; 
      treeView1.Width = 50; 
     } 
    } 

Событие Application.Idle также работает слишком просто, просто немного неудобно.

+0

Это сработало отлично, спасибо! –

2

Спасибо, что Tip имел ту же проблему, я изменил событие timer_Tick, чтобы включить полосу прокрутки, добавив 20 к ширине.

private void tmrListPos_Tick(object sender, EventArgs e) 
    { 
     Point posLB = clbPlants.PointToClient(Cursor.Position); 
     Rectangle rectPlants = clbPlants.DisplayRectangle; 
     rectPlants.Width = rectPlants.Size.Width + 20; 
     if (!rectPlants.Contains(posLB)) 
     { 
      tmrListPos.Enabled = false; 
      clbPlants.Size = clbPlants.MinimumSize; 
     } 
    } 
Смежные вопросы