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

时间:2013-07-31 05:41:08

标签: c# wpf

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

enter image description here

但是我想禁用它意味着它应该是这样的:

enter image description here

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

4 个答案:

答案 0 :(得分:20)

试试这个:

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 MF_ENABLED = 0x00000000;

    const uint SC_CLOSE = 0xF060;

    const int WM_SHOWWINDOW = 0x00000018;
    const int WM_CLOSE = 0x10;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

    }

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

        HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;

        if (hwndSource != null)
        {
            hwndSource.AddHook(new HwndSourceHook(this.hwndSourceHook));
        }
    }


    IntPtr hwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_SHOWWINDOW)
        {
            IntPtr hMenu = GetSystemMenu(hwnd, false);
            if (hMenu != IntPtr.Zero)
            {
                EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
            }
        }
        else if (msg == WM_CLOSE)
        {
            handled = true;
        }
        return IntPtr.Zero;
    }
}

(取自此处:http://blogs.microsoft.co.il/blogs/tamir/archive/2007/09/26/never-ever-close-me-how-to-disable-close-button-in-wpf.aspx

确保将ResizeMode设置为NoResize

答案 1 :(得分:4)

您必须覆盖并在 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;
}

答案 2 :(得分:1)

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

我这样做了:获取CustomChromeWindow(最终看起来与图片中的完全一样),然后将Command()属性绑定到viewmodel,然后设置CanExecuteCommand = false,这将禁用该按钮({ {3}})。

我也可以这样:How does one "disable" a button in WPF using the MVVM pattern?

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

答案 3 :(得分:1)

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>