MouseLeave event fires when moving over control's ScrollBar

自闭症网瘾萝莉.ら 提交于 2020-05-13 04:13:09

问题


I am reposting this question due to inability to solve the problem (original here).

In the TreeView, ListBox, or it seems from my google searches anything with a ScrollBar, the ScrollBar is not considered a part of the control.

I have a TreeView that I'm putting into a custom control, and it's Dock Fill. So there it acts as a custom TreeView which has all our logic to manage it in one place.

In parts of our program we slide it out based on a MouseEnter event, and slide it back in on a MouseLeave event, however we are currently using a 3rd party library's TreeView for this, which I have been tasked with replacing.

So I've moved everything over to the Windows TreeView, but can not find a way to reliable capture the MouseLeave -only- if it leaves the entire TreeView, scrollbar included.

I've seen one hackish solution of wrapping it in a panel with several pixels and capturing the MouseLeave of the panel, but I hardly believe this is what Microsoft had intended us to do in this situation.

In Short:

The ScrollBar does not fire MouseEnter or MouseLeave for the control, and that makes using MouseEnter/MouseLeave for sliding out the control unusable since the user can not use the ScrollBar.

What is the preferred way to handle this situation?

In the previous question I was given the advice to use Spy++ and attempt to attach to WndProc() to handle MouseEnter/MouseLeave for the ScrollBar.

This however did not work as the messages Spy++ showed were not firing in the WndProc() at form level, or control level. It's as if .NET just can't see the ScrollBar.

Using WndProc() also seems unrealistic for such a simple request, is there any other way to do this, or if WndProc() is the only way, has anyone actually been able to achieve this and show me how?


回答1:


There is no clean solution for this. Your panel trick doesn't work either, it will be completely missed when the user moves the mouse quickly.

Punt. Once you get MouseEnter, start a 200 msec Timer. In the Tick event, check if the mouse is still hovering the tree view. For example:

    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;
        }
    }

The Application.Idle event works too btw, just a wee bit more awkward.




回答2:


Thanks for the Tip was having the same issue, I modified the timer_Tick event to include the scrollbar by adding 20 to the width.

    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;
        }
    }


来源:https://stackoverflow.com/questions/3391004/mouseleave-event-fires-when-moving-over-controls-scrollbar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!