c# - 暂时禁用关闭按钮

标签 c# winforms

我需要暂时禁用关闭按钮(应该允许最小化和最大化)。

我尝试过的每个解决方案都会禁用所有 按钮或只是永久禁用关闭按钮。有什么办法可以暂时做到吗?

最佳答案

永久禁用关闭按钮的方法是设置 CS_NOCLOSE style对于窗体的窗口类。要从 WinForms 应用程序执行此操作,您需要覆盖表单的 CreateParams property并使用 | 运算符添加 SC_NOCLOSE 标志,例如:

protected override CreateParams CreateParams
{
    get
    {
        const int CS_NOCLOSE = 0x200;
        CreateParams cp = base.CreateParams;
        cp.ClassStyle = cp.ClassStyle | CS_NOCLOSE;
        return cp;
    }
}

不过,这是一个永久性的解决方案,因为您无法即时更新窗口类样式。您将不得不销毁并重新创建窗口类。

但是,您可以改为禁用系统菜单中的“关闭”命令,这也会自动禁用标题栏中的关闭按钮。

internal static class NativeMethods
{
    public const int SC_CLOSE     = 0xF060;
    public const int MF_BYCOMMAND = 0;
    public const int MF_ENABLED   = 0;
    public const int MF_GRAYED    = 1;

    [DllImport("user32.dll")]
    public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool revert);

    [DllImport("user32.dll")]
    public static extern int EnableMenuItem(IntPtr hMenu, int IDEnableItem, int enable);
}

public class MyForm : Form
{

    // ...

    // If "enable" is true, the close button will be enabled (the default state).
    // If "enable" is false, the Close button will be disabled.
    bool SetCloseButton(bool enable)
    {
        IntPtr hMenu = NativeMethods.GetSystemMenu(this.Handle, false);
        if (hMenu != IntPtr.Zero)
        {
            NativeMethods.EnableMenuItem(hMenu,
                                         NativeMethods.SC_CLOSE,
                                         NativeMethods.MF_BYCOMMAND | (enable ? NativeMethods.MF_ENABLED : NativeMethods.MF_GRAYED));                                
        }
    }   
}

请注意,这确实是一个 transient 操作。如果您任何导致系统菜单被框架修改(例如最大化或最小化表单),您的修改将被抹去。更多详情请见 my related answer here .这通常是一个问题,也是您更愿意使用第一种解决方案的原因。但在这种情况下,由于您想动态禁用和重新启用,所以没什么大不了的。

最后,请注意您提出的建议与 Windows UI Guidelines for dialog boxes 背道而驰。 .他们说,从本质上讲,用户希望看到一个关闭按钮,它的存在给了他们一种安全感,让他们始终可以安全地“退出”屏幕上弹出的任何内容。因此,您不应该禁用它。它确实调用了一个进度对话框作为一个异常(exception),但它继续说进度对话框应该总是有一个允许中止操作的“取消”按钮。在这种情况下,您可以简单地让标题栏中的关闭按钮调用此“取消”按钮——无需禁用它。

关于c# - 暂时禁用关闭按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25322055/

相关文章:

c# - DateTime.AddYears 在闰年的行为

c# - 需要建议 : alternative to overloading "is" and "as" operators in . NET

c# - 如何从 BackgroundWorker 调用 WebBrowser.Navigate()?

c# - 使用 Visual C# 在多个 Windows 窗体应用程序中形成关闭事件

c# - Control.Focus() 错误

c# - 无法转换为 microsoft.azure.cosmosDB.table.itableentity

c# - C# 中的构造函数

c# - 从 .NET 查看的命名空间列表中删除 MyCompany.Task

c# - 我在哪里可以获得 "open hand"/"closed hand"鼠标光标?

c# - 使用 AutoSize=false 防止标签自动换行