C# Windows 窗体 - 在控件外部单击后隐藏控件

C# WindowsForms - Hide control after clicking outside of it

C# WindowsForms - 在控件外部单击后隐藏控件

我有一个默认情况下不可见的图片框 (f.e.picturebox1)。当我单击一个按钮(假设是 button1)时,将显示 picturebox1。现在 -> 我需要 picturebox1 在我单击它的外部时再次隐藏(在表单本身或任何其他控件上)。它的工作原理与上下文菜单的工作原理相同。

我不知道该怎么做,因为任何 "Click_Outside" 事件都不存在。有什么简单的方法可以做到这一点吗?谢谢。

使用控件的 LostFocus 事件(在您的情况下,是 PictureBox 控件)

如您所说,ClickOutside 不存在,因此您的选择很少:

遍历表单的所有控件 (Form.Controls) 并添加一个单击事件以隐藏除 "Show" 按钮之外的 PictureBox。

您可以像本例一样在源头拦截鼠标点击消息:intercept

这是一个简单的解决方案,尽管不是完全容易完全理解的解决方案,因为它确实涉及捕获 WndProc 事件并使用 Windows inderds 中的一些常量..:

这是显而易见的部分:

private void button1_Click(object sender, EventArgs e)
{
    pictureBox1.Show();
}

不幸的是我们不能使用pictureBox1.LostFocus事件来隐藏Picturebox

那是因为只有一些 控件在单击它们时实际上可以获得焦点; Button 或其他交互式控件,如 ListBoxCheckBox 等也可以。

但是 PanelPictureBox 以及 Form 本身无法通过这种方式获得焦点。所以我们需要一个更全球化的解决方案。

解决方案往往来自 Windows 消息系统的深处:

const int WM_PARENTNOTIFY = 0x210;
const int WM_LBUTTONDOWN = 0x201;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_LBUTTONDOWN || (m.Msg == WM_PARENTNOTIFY && 
        (int)m.WParam == WM_LBUTTONDOWN))
        if (!pictureBox1.ClientRectangle.Contains( 
                         pictureBox1.PointToClient(Cursor.Position))) 
            pictureBox1.Hide();
    base.WndProc(ref m);
}

请注意,我们需要确保您仍然可以点击 PictureBox 本身;所以我们检查鼠标是否在其 ClientRectangle..

只需将其添加到表单代码中,每次在 PictureBox 外部单击都会将其隐藏。

最简单的方法是这样的: 将以下方法复制并粘贴到代码中的任意位置:

private void mouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left && pictureBox1.Visible == true)
            pictureBox1.Visible = false;
    }

然后在您的 form_Load 活动中复制并粘贴以下代码:

foreach (Control ctrl in this.Controls)
    if (ctrl is GroupBox || ctrl is .....)
        ctrl.MouseClick += mouseClick;

当然,您应该为另一个 groupBox 中的每个 groupBox 重复此循环,并根据您拥有的控件将点替换为文本框、按钮、组合框、标签...