我正在WPF中写一个模态对话框。我如何设置一个WPF窗口没有关闭按钮?我仍然希望它的WindowState有一个正常的标题栏。

我找到了ResizeMode、WindowState和WindowStyle,但这些属性都不允许我隐藏关闭按钮,而是显示标题栏,就像在模态对话框中一样。


当前回答

XAML 代码

<Button Command="Open" Content="_Open">
    <Button.Style>
        <Style TargetType="Button">
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Visibility" Value="Collapsed" />
                </Trigger>
            </Style.Triggers>
        </Style>
     </Button.Style>
</Button>

应该工作

编辑-在你的瞬间,这个线程展示了如何做到这一点,但我不认为窗口有一个属性来获得你想要的而不失去正常的标题栏。

编辑2 这个线程展示了一种方法,但你必须将自己的风格应用到系统菜单,它展示了一种方法,你可以这样做。

其他回答

正如在其他答案中所述,您可以使用WindowStyle="None"来完全删除标题栏。

并且,正如其他答案的评论中所述,这阻止了窗口的可拖动性,因此很难将其从初始位置移动。

但是,你可以通过在窗口的代码后面文件的构造函数中添加一行代码来克服这个问题:

MouseDown += delegate { DragMove(); };

或者,如果你喜欢Lambda语法:

MouseDown += (sender, args) => DragMove();

这使得整个窗口可拖动。窗口中出现的任何交互控件,如按钮,仍将正常工作,不会作为窗口的拖拽句柄。

如果需要的只是禁止用户关闭窗口,这是一个简单的解决方案。

XAML守则: IsCloseButtonEnabled =“虚假”

它挡住了按钮。

WPF没有一个内置的属性来隐藏标题栏的关闭按钮,但是你可以用几行P/Invoke来做到这一点。

首先,将这些声明添加到Window类中:

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

然后把下面的代码放到Window的Loaded事件中:

var hwnd = new WindowInteropHelper(this).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);

这样就没有关闭按钮了。你也不会在标题栏的左边有一个窗口图标,这意味着没有系统菜单,即使你右键单击标题栏——它们都在一起。

重要提示:所有这些都是隐藏按钮。用户仍然可以关闭窗口!如果用户按下Alt+F4,或者通过任务栏关闭应用程序,窗口仍然会关闭。

如果你不想让窗口在后台线程完成之前关闭,那么你也可以覆盖OnClosing并将Cancel设置为true,就像Gabe建议的那样。

使用WindowStyle="SingleBorderWindow",这将隐藏WPF窗口的最大和最小按钮。

我尝试了Viachaslau的答案,因为我喜欢不移除按钮而是禁用它的想法,但由于某种原因,它并不总是有效:关闭按钮仍然被启用,但没有任何错误。

另一方面,这总是有效的(错误检查省略):

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

private const uint MF_BYCOMMAND = 0x00000000;
private const uint MF_GRAYED = 0x00000001;
private const uint SC_CLOSE = 0xF060;
private const int WM_SHOWWINDOW = 0x00000018;

protected override void OnSourceInitialized( EventArgs e )
{
  base.OnSourceInitialized( e );
  var hWnd = new WindowInteropHelper( this );
  var sysMenu = GetSystemMenu( hWnd.Handle, false );
  EnableMenuItem( sysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED );
}