禁用 WPF 窗口标题栏中的关闭按钮 (C#)

Posted

技术标签:

【中文标题】禁用 WPF 窗口标题栏中的关闭按钮 (C#)【英文标题】:Disable Close Button In Title Bar of a WPF Window (C#) 【发布时间】:2013-07-31 12:13:16 【问题描述】:

我想知道如何禁用(而不是删除/隐藏)WPF 窗口中的关闭按钮。我知道如何隐藏它,使窗口的标题栏看起来像这样:

但我想禁用它,这意味着它应该如下所示:

我正在使用 C# 编写脚本并使用 WPF (Windows Presentation Foundation)。

【问题讨论】:

我找到了这个链接看看这个[链接][1]能不能帮忙:[1]:***.com/questions/743906/… 【参考方案1】:

试试这个:

public partial class MainWindow : Window


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

    [DllImport("user32.dll")]
    static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);


    const uint MF_BYCOMMAND = 0x00000000;
    const uint MF_GRAYED = 0x00000001;

    const uint SC_CLOSE = 0xF060;

    public MainWindow()
    
        InitializeComponent();
    

    protected override void OnSourceInitialized(EventArgs e)
    
        base.OnSourceInitialized(e);

        // Disable close button
        IntPtr hwnd = new WindowInteropHelper(this).Handle;
        IntPtr hMenu = GetSystemMenu(hwnd, false);
        if (hMenu != IntPtr.Zero)
        
            EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
        
    

取自here(编辑:链接已损坏)。

确保将ResizeMode 设置为NoResize

【讨论】:

【参考方案2】:

您必须在 OnCLosing 事件中覆盖并设置 e.cancel=true

public MyWindow()

    InitializeComponent();
    this.Closing += new System.ComponentModel.CancelEventHandler(MyWindow_Closing);


void MyWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)

    e.Cancel = true;

【讨论】:

这不会让按钮看起来像是被禁用了。 是的,但我想真正禁用关闭按钮,而不是让它取消关闭。 恐怕您只能在 WPF 中隐藏或覆盖,请看看这个***.com/questions/743906/… @Kyle ***.com/a/1623991/743382 在该页面上似乎 正是 OP 在这里寻找的。 (编辑:我看到它做了一点点,而且一点点很容易删除。) @hvd 链接中选择的答案会永久从窗口中删除关闭图标,输出类似于此问题中用户不想要的第一张图片。我希望我说清楚 【参考方案3】:

This post 哪个答案使用BehaviorGetWindowLongSetWindowLong

public class HideCloseButtonOnWindow : System.Windows.Interactivity.Behavior<Window>

    #region bunch of native methods

    private const int GWL_STYLE = -16;
    private const int WS_SYSMENU = 0x80000;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    #endregion

    protected override void OnAttached()
    
        base.OnAttached();
        AssociatedObject.Loaded += OnLoaded;
    

    protected override void OnDetaching()
    
        AssociatedObject.Loaded -= OnLoaded;
        base.OnDetaching();
    

    private void OnLoaded(object sender, RoutedEventArgs e)
    
        var hwnd = new System.Windows.Interop.WindowInteropHelper(AssociatedObject).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    

使用方法:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:w="clr-namespace:WpfApplication2">

<i:Interaction.Behaviors>
    <w:HideCloseButtonOnWindow />
</i:Interaction.Behaviors>

</Window>

【讨论】:

这不会让关闭按钮看起来像是被禁用了,而是将其完全移除。【参考方案4】:

你也许可以用 win32 hackery 做到这一点。

我是这样做的:获取CustomChromeWindow(最终看起来与图片中的一模一样),并将Command()属性绑定到viewmodel,然后设置CanExecuteCommand = false,这将使按钮禁用(@ 987654321@)。

我也可能这样:How to disable close button on a window in another process with C++?

基本上,使用 pInvoke 调用该代码。您可以轻松获取 WPF 窗口句柄。

【讨论】:

以上是关于禁用 WPF 窗口标题栏中的关闭按钮 (C#)的主要内容,如果未能解决你的问题,请参考以下文章

WPF 在属性栏中更改相关设置

C# WPF: 在一个窗体上设置一个按钮,点击这个按钮时,打开新窗体并关闭原窗体?

C# winform 父窗口子窗口按钮控制

从框架内关闭 wpf 窗口

关于wpf中按钮关闭原窗口,开启新窗口

WPF中,怎样设置点击按钮关闭当前窗口