我想知道如何禁用(不删除/隐藏)WPF窗口中的“关闭”按钮。我知道如何隐藏它使窗口的标题栏看起来像这样:
但是我想禁用它意味着它应该是这样的:
我正在使用C#编写脚本并使用WPF(Windows Presentation Foundation)。
答案 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;
}
}
确保将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使用Behavior
,GetWindowLong
和SetWindowLong
的回答:
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>