C# 关于边界和行为

标签 c# .net winforms

我正在尝试在 Windows 窗体应用程序上进行智能控制。

首先是一个普通按钮(“大按钮”)。在 MouseHover 上,它会隐藏自己,同时会出现一个面板。面板内部有四个小按钮。它们各自代表一个“快速行动”。当鼠标离开面板时,大按钮应该出现,面板本身应该隐藏。

面板

面板是一个普通的用户控件。它包含四个带边框的普通按钮(嵌套按钮)。

它仅在鼠标悬停在面板上时可见。

enter image description here

大按钮

大按钮只是一个普通按钮。它是可见的(并且可以点击),但只有在 MouseHover 事件未被触发时才会出现。

Big Button

问题

问题是我无法捕获面板MouseLeave 事件。这是因为它里面有嵌套按钮,这意味着每次鼠标移到嵌套按钮上时,面板MouseLeave 事件都会被触发。

一种方法

我试图通过实现嵌套按钮面板MouseLeave 事件来防止这种情况发生。每次触发 MouseLeave 事件时,我都会检查鼠标是否仍在 面板 的矩形内。

漏洞

上一段中描述的方法效果不错,但有一个问题。每次鼠标越过边界(主要是嵌套按钮)时,MouseLeave 事件捕获的MousePosition 都是错误的。通常它在一个消极和随机的地方。

我使用以下代码检查 MousePosition:

panelRectangle.Contains(PointToClient(MousePosition))

(MousePosition 是从窗体的角度来看的,但这并不能解释为什么有时位置为负,如果嵌套按钮位于窗体的中间)。

问题

如何查看鼠标是否在面板内?主要问题是边界。当鼠标位于嵌套按钮的边框上时,为什么我的 MousePosition 位于随机位置?

这是一些其他代码:

        bool bInsideRectangle = 
        Rectangle panelRectangle = new Rectangle(this.panelContainer.Location, this.panelContainer.Size);

        if (panelRectangle.Contains(PointToClient(Control.MousePosition)) || PointToClient(Control.MousePosition).X < 0 || PointToClient(Control.MousePosition).Y < 0)
        {
            bInsideRectangle = true;
        }

        //bool bIsInsideOfPanel = this.panelContainer.ClientRectangle.Contains(PointToClient(Control.MousePosition));
        //bool bIsInsideOfButton1 = this.button1.ClientRectangle.Contains(PointToClient(Control.MousePosition));
        //bool bIsInsideOfButton2 = this.button2.ClientRectangle.Contains(PointToClient(Control.MousePosition));
        //bool bIsInsideOfButton3 = this.button3.ClientRectangle.Contains(PointToClient(Control.MousePosition));
        //bool bIsInsideOfButton4 = this.button4.ClientRectangle.Contains(PointToClient(Control.MousePosition));

        // Check if the mouse is not inside of those child-controls.
        if(!bInsideRectangle)
        //if (!bIsInsideOfPanel && !bIsInsideOfButton1 && !bIsInsideOfButton2 && !bIsInsideOfButton3 && !bIsInsideOfButton4)
        {
            this.panelContainer.Visible = false;
            this.buttonBig.Visible = true;
        }

最佳答案

创建一个小助手,告诉您鼠标是否在控件的边界内

// The helper relies on "MousePosition" member of the form
// so this function has to be in the form, or you find another way to do the check
bool isMouseInControl(Control control)
{
    return control.ClientRectangle.Contains(control.PointToClient(MousePosition));
}

现在将 MouseEnter 和 MouseLeave 绑定(bind)到你的大按钮

bigButton.MouseEnter += bigButton_MouseEnter;
bigButton.MouseLeave += bigButton_MouseLeave;

记住子菜单的当前状态 (bool) bool submenu = false;

现在您可以像这样检查正确的离开/进入:

    void bigButton_MouseLeave(object sender, EventArgs e)
    {
        if(submenu && !isMouseInControl(sender as Control))
        {
            submenu = false;
            // Disable submenu here
        }
    }


    void bigButton_MouseEnter(object sender, EventArgs e)
    {
        if(submenu || isMouseInControl(sender as Control))
        {
            submenu = true;
            // Enable submenu here
        }
    }

bool submenu 是可选的,因为它只在不需要时阻止检查(据我所知,它只对 mouseenter 起作用...)

关于C# 关于边界和行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24183219/

相关文章:

c# - 我从 C# 调用带有 2 个参数(输入和输出)的存储过程,但输出参数的值不显示

c# - 当 MSTest 在 TestInitialize 中失败时,为什么不执行 TestCleanup?

.net - 您对 MS CAB(复合应用程序 block )有何看法?

c# - 通过编写 C dll 来加速 C# 中的数学代码?

c# - WinForm 应用程序中的沙漏问题

c# - 当我按下 Alt 键时,如何防止控制框获得焦点?

c# - 删除datagridview中的多行

c# - DateTime.UtcNow 的结果不一致

c# - 我如何获得 XElement 的第一个 child ?

c# - 如何在计时器触发的函数上强制执行单例行为?