wpf 窗口取消关闭按钮
时间: 2025-05-24 17:32:27 浏览: 17
### 如何在 WPF 中禁用或隐藏窗口的关闭按钮
在 WPF 应用程序中,可以通过多种方式来实现禁用或隐藏窗口的关闭按钮。以下是几种常见的方法及其对应的代码示例。
#### 方法一:通过设置 `ResizeMode` 和附加属性
可以利用 `ResizeMode="NoResize"` 来阻止用户调整窗口大小,并结合自定义行为类中的附加属性来隐藏关闭按钮[^1]。
```xml
<Window x:Class="WafClient.Presentation.Views.SampleWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:model="clr-namespace:EGIS.MISPlatform.Model;assembly=EGIS.MISPlatform"
ResizeMode="NoResize"
model:WindowBehavior.HideCloseButton="True">
</Window>
```
此方法依赖于附加属性 `HideCloseButton` 的逻辑,在后台代码中需要注册该属性并处理其变化回调函数[^2]:
```csharp
public static class WindowBehavior
{
public static readonly DependencyProperty HideCloseButtonProperty =
DependencyProperty.RegisterAttached(
"HideCloseButton",
typeof(bool),
typeof(WindowBehavior),
new PropertyMetadata(false, OnHideCloseButtonChanged));
public static bool GetHideCloseButton(DependencyObject obj)
{
return (bool)obj.GetValue(HideCloseButtonProperty);
}
public static void SetHideCloseButton(DependencyObject obj, bool value)
{
obj.SetValue(HideCloseButtonProperty, value);
}
private static void OnHideCloseButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Window window && (bool)e.NewValue)
{
var helper = new WindowInteropHelper(window);
if (helper.EnsureHandle())
{
NativeMethods.RemoveMenu(NativeMethods.GetSystemMenu(helper.Handle, false), NativeMethods.SC_CLOSE, NativeMethods.MF_BYCOMMAND);
}
}
}
}
internal static class NativeMethods
{
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
internal static extern IntPtr GetSystemMenu(IntPtr hWnd, uint bRevert);
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
internal static extern uint RemoveMenu(IntPtr hMenu, uint nPosition, uint wFlags);
internal const uint SC_CLOSE = 0xF060;
internal const uint MF_BYCOMMAND = 0x0;
}
```
这种方法的优点在于它封装了复杂的互操作调用细节,使 XAML 文件更加简洁易读[^2]。
---
#### 方法二:直接使用 PInvoke 调用 WinAPI 函数
如果不想引入额外的行为类,则可以直接在窗口加载时调用 Windows API 移除菜单项[^3]。
```csharp
using System.Runtime.InteropServices;
public partial class MainWindow : Window
{
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, UInt32 bRevert);
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
private static extern UInt32 RemoveMenu(IntPtr hMenu, UInt32 nPosition, UInt32 wFlags);
private const UInt32 SC_CLOSE = 0x0000F060;
private const UInt32 MF_BYCOMMAND = 0x00000000;
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var hwnd = new WindowInteropHelper(this).Handle;
if (hwnd != IntPtr.Zero)
{
IntPtr hMenu = GetSystemMenu(hwnd, 0);
if (hMenu != IntPtr.Zero)
{
RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}
}
}
}
```
这种方式简单明了,适合小型项目或者不需要频繁修改场景下的快速开发需求[^3]。
---
#### 方法三:覆盖 `OnClosing` 或 `OnClosed` 方法
虽然不建议完全重写这些事件(因为可能导致无法正常退出),但在某些特殊情况下也可以考虑拦截窗口关闭动作[^1]。
```csharp
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
MessageBox.Show("窗口不允许被关闭!");
e.Cancel = true;
}
```
需要注意的是,这种做法会让用户即使点击任务栏上的关闭选项也无法成功终止应用进程,除非手动结束任务管理器中的实例。
---
### 总结
以上介绍了三种不同的技术手段用于解决如何在 WPF 程序里屏蔽掉顶部右上角的标准“X”形关闭按键问题。每种方案各有优劣,请依据实际业务环境选取最合适的那一种实施即可。
阅读全文
相关推荐


















