【问题标题】:Detect if cursor is within the bounds of a control检测光标是否在控件的范围内
【发布时间】:2012-09-21 04:22:08
【问题描述】:

我有一个用户控件

public partial class UserControl1 : UserControl, IMessageFilter
{
    public UserControl1()
    {
        InitializeComponent();
        Application.AddMessageFilter(this);
    }

    public bool PreFilterMessage(ref Message m)
    {
        var mouseLocation = Cursor.Position;

        if (Bounds.Contains(PointToClient(mouseLocation)))
        {
            bool aBool = true;//breakpoint
            bool two = aBool;//just assignment so compiler doesn't optimize my bool out
        }
        if (m.Msg != 0x20a) // Scrolling Message
        {
            return false;//ignore message
        }
        return false;
    }
}

当我漂浮在包含在父窗体中的用户控件上时,断点不会被命中。断点在附近被击中,但我可以在用户控件内的实际文本框中而不被击中。如何准确确定我是否在此用户控件的范围内?

FWIW,我有两台显示器。我使用的显示器似乎没有什么区别。

【问题讨论】:

  • @DanielA.White 我在您的链接中看到的答案是针对单个控件的。请注意,我在这里连接到一个全局消息过滤器。我认为那些行不通。最终我需要确切地知道鼠标在哪个控件上,而不仅仅是包含子控件的一般用户控件。

标签: c# winforms


【解决方案1】:

尝试针对 Control.ClientRectangle 而不是 Control.Bounds 进行命中测试:

if (ClientRectangle.Contains(PointToClient(Control.MousePosition))) {
    bool aBool = true;//breakpoint 
    bool two = aBool;
}

【讨论】:

  • 如果这是来自MouseEventArgs,您甚至可以从中获取Location 属性,而无需PointToClient
【解决方案2】:

只是为了快速技巧,您可以通过一个事件触发所有用户控件的控件并处理鼠标悬停事件。 例如,如果您的用户控件中有两个文本框

    textBox1.MouseMove += new MouseEventHandler(controls_MouseMove);
    textBox2.MouseMove += new MouseEventHandler(controls_MouseMove);
    ...

    void controls_MouseMove(object sender, MouseEventArgs e)
    {
        Control subc=sender as Control;
        int mouseX = MousePosition.X;
        ....
    }

【讨论】:

  • 请记住,至少有一些控件在收到鼠标按下事件时会触发 mousemove 事件。我发现处理这个问题的最好方法是在鼠标移动的事件处理程序中仔细检查鼠标指针是否确实在控件之外。
  • MousePosition.X 是鼠标在表单中的大致位置。如果您在面板内有按钮,并且面板不在表单的起点,这会给您无效的结果
猜你喜欢
  • 2012-07-05
  • 1970-01-01
  • 2023-03-16
  • 2017-02-28
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多