18

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

在此处输入图像描述

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

在此处输入图像描述

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

4

4 回答 4

24

尝试这个:

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);
        }
    }
}

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

确保将 设置ResizeModeNoResize

于 2013-07-31T05:57:58.743 回答
3

您必须覆盖并在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;
}
于 2013-07-31T05:46:07.790 回答
1

这篇文章的答案使用Behavior,GetWindowLongSetWindowLong:

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>
于 2017-02-21T09:55:22.710 回答
0

你可能可以用win32hackery做到这一点。

我是这样做的:获取CustomChromeWindow(最终看起来与图片中的一模一样),并将Command()属性绑定到viewmodel,然后设置CanExecuteCommand = false,这将使按钮被禁用(如何一个“使用 MVVM 模式禁用”WPF 中的按钮?)。

我也可能有这种方式:如何使用 C++ 在另一个进程中禁用窗口上的关闭按钮?

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

于 2013-07-31T05:47:28.077 回答