C#ListBox.MouseEnter / MouseLeave和滚动条

问题描述 投票:1回答:2

我在表单的左侧有一个列表框。用户可以选择“自动隐藏”它,以便它消失在左侧,并且仅在用户将鼠标移到它上时才重新出现。

如果ListBox中的项目很少,则此功能可以很好地工作。

但是,一旦我在列表框中放入足够的项目,以便现在有了滚动条,有趣的事情就会开始发生。仅当用户将鼠标移到滚动条上方的ListBox中时,才会触发MouseEnter代码。这意味着我必须拥有比滚动条更大的宽度,否则它们将永远无法显示它。

此外,如果ListBox不在焦点上,则用户根本无法滚动。如果他们尝试单击滚动条进行滚动,列表框将消失。如果他们在列表框内单击以将其聚焦(以便可以使用鼠标滚轮滚动),则他们将失去选择。

有什么方法可以扩展MouseEnter和MouseLeave的边界以包括滚动条?

c# winforms listbox mouseover
2个回答
1
投票
作为一种解决方法,您可以从ListBox继承并重写WndProc()以查看WM_NCMOUSEMOVE消息(m.Msg == 0xa0)。或一个200毫秒的计时器,用于检查鼠标的位置。

0
投票
我仍然使用MouseEnter来放大ListBox。但是,与其让ListBox使用MouseLeave缩小大小,不如让我发现实际上将其放大直到用户在窗体上的其他任何地方单击都更好。我在窗体上其他任何地方捕获MouseDown事件,然后在用户单击窗体上除ListBox之外的任何位置时,将ListBox缩小到原始大小。

在表单构造器中,我放置了此循环:

foreach (Control control in Controls) { control.MouseDown += RedirectMouseDown; }

然后创建此方法:

    private void RedirectMouseDown(object sender, MouseEventArgs e)
    {
        Control control = (Control)sender;
        Point screenPoint = control.PointToScreen(new Point(e.X, e.Y));
        Point formPoint = PointToClient(screenPoint);
        MouseEventArgs args = new MouseEventArgs(e.Button, e.Clicks, formPoint.X, formPoint.Y, e.Delta);            
        OnMouseDown(args);
    }

然后在窗体的MouseDown事件中:

    if (!listBox1.ClientRectangle.Contains(listBox1.PointToClient(Control.MousePosition)))
    {
        if (listBox1.Size.Width == 500)
        {
            listBox1.Size = new Size(listBox1.Size.Width - 200, listBox1.Size.Height);
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.