如何在WPF窗口中隐藏关闭按钮?

时间:2023-02-01 17:03:42

I'm writing a modal dialog in WPF. How do I set a WPF window to not have a close button? I'd still like for its WindowState to have a normal title bar.

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

I found ResizeMode, WindowState, and WindowStyle, but none of those properties allow me to hide the close button but show the title bar, as in modal dialogs.

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

19 个解决方案

#1


241  

WPF doesn't have a built-in property to hide the title bar's Close button, but you can do it with a few lines of P/Invoke.

WPF没有内置属性来隐藏标题栏的关闭按钮,但是您可以使用几行P/Invoke。

First, add these declarations to your Window class:

首先,将这些声明添加到窗口类:

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

Then put this code in the Window's Loaded event:

然后将此代码放入窗口已加载的事件中:

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

And there you go: no more Close button. You also won't have a window icon on the left side of the title bar, which means no System menu, even when you right-click the title bar -- they all go together.

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

Note that Alt+F4 will still close the Window. If you don't want to allow the window to close before the background thread is done, then you could also override OnClosing and set Cancel to true, as Gabe suggested.

注意,Alt+F4仍然会关闭窗口。如果您不想让窗口在后台线程完成之前关闭,那么您也可以重写onclose并将Cancel设置为true,正如Gabe所建议的那样。

#2


79  

I just got to similar problem and Joe White's solution seems to me simple and clean. I reused it and defined it as an attached property of Window

我刚刚遇到了类似的问题,乔·怀特的解决方案在我看来简单明了。我重新使用它并将它定义为窗口的附加属性

public class WindowBehavior
{
    private static readonly Type OwnerType = typeof (WindowBehavior);

    #region HideCloseButton (attached property)

    public static readonly DependencyProperty HideCloseButtonProperty =
        DependencyProperty.RegisterAttached(
            "HideCloseButton",
            typeof (bool),
            OwnerType,
            new FrameworkPropertyMetadata(false, new PropertyChangedCallback(HideCloseButtonChangedCallback)));

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static bool GetHideCloseButton(Window obj) {
        return (bool)obj.GetValue(HideCloseButtonProperty);
    }

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static void SetHideCloseButton(Window obj, bool value) {
        obj.SetValue(HideCloseButtonProperty, value);
    }

    private static void HideCloseButtonChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var window = d as Window;
        if (window == null) return;

        var hideCloseButton = (bool)e.NewValue;
        if (hideCloseButton && !GetIsHiddenCloseButton(window)) {
            if (!window.IsLoaded) {
                window.Loaded += HideWhenLoadedDelegate;
            }
            else {
                HideCloseButton(window);
            }
            SetIsHiddenCloseButton(window, true);
        }
        else if (!hideCloseButton && GetIsHiddenCloseButton(window)) {
            if (!window.IsLoaded) {
                window.Loaded -= ShowWhenLoadedDelegate;
            }
            else {
                ShowCloseButton(window);
            }
            SetIsHiddenCloseButton(window, false);
        }
    }

    #region Win32 imports

    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

    private static readonly RoutedEventHandler HideWhenLoadedDelegate = (sender, args) => {
        if (sender is Window == false) return;
        var w = (Window)sender;
        HideCloseButton(w);
        w.Loaded -= HideWhenLoadedDelegate;
    };

    private static readonly RoutedEventHandler ShowWhenLoadedDelegate = (sender, args) => {
        if (sender is Window == false) return;
        var w = (Window)sender;
        ShowCloseButton(w);
        w.Loaded -= ShowWhenLoadedDelegate;
    };

    private static void HideCloseButton(Window w) {
        var hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    }

    private static void ShowCloseButton(Window w) {
        var hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_SYSMENU);
    }

    #endregion

    #region IsHiddenCloseButton (readonly attached property)

    private static readonly DependencyPropertyKey IsHiddenCloseButtonKey =
        DependencyProperty.RegisterAttachedReadOnly(
            "IsHiddenCloseButton",
            typeof (bool),
            OwnerType,
            new FrameworkPropertyMetadata(false));

    public static readonly DependencyProperty IsHiddenCloseButtonProperty =
        IsHiddenCloseButtonKey.DependencyProperty;

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static bool GetIsHiddenCloseButton(Window obj) {
        return (bool)obj.GetValue(IsHiddenCloseButtonProperty);
    }

    private static void SetIsHiddenCloseButton(Window obj, bool value) {
        obj.SetValue(IsHiddenCloseButtonKey, value);
    }

    #endregion

}

Then in XAML you just set it like this:

在XAML中,你只需要这样设置:

<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:u="clr-namespace:WafClient.Presentation.Behaviors"
    ResizeMode="NoResize"
    u:WindowBehavior.HideCloseButton="True">
    ...
</Window>

#3


53  

Set WindowStyle property to None which will hide the control box along with the title bar. No need to kernal calls.

将WindowStyle属性设置为None,该属性将隐藏控件框和标题栏。没有必要打电话。

#4


48  

This won't get rid of the close button, but it will stop someone closing the window.

这不会消除关闭按钮,但它会阻止某人关闭窗口。

Put this in your code behind file:

把这个放在你的代码后面的文件:

protected override void OnClosing(CancelEventArgs e)
{
   base.OnClosing(e);
   e.Cancel = true;
}

#5


15  

To disable close button you should add the following code to your Window class (the code was taken from here, edited and reformatted a bit):

要禁用关闭按钮,您应该向窗口类添加以下代码(代码从这里开始,编辑并重新格式化):

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

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

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

}

private bool allowClosing = false;

[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;
private const int WM_CLOSE = 0x10;

private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case WM_SHOWWINDOW:
            {
                IntPtr hMenu = GetSystemMenu(hwnd, false);
                if (hMenu != IntPtr.Zero)
                {
                    EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
                }
            }
            break;
        case WM_CLOSE:
            if (!allowClosing)
            {
                handled = true;
            }
            break;
    }
    return IntPtr.Zero;
}

This code also disables close item in System menu and disallows closing the dialog using Alt+F4.

此代码还禁止在系统菜单中关闭项,并禁止使用Alt+F4关闭对话框。

You will probably want to close the window programmatically. Just calling Close() will not work. Do something like this:

您可能希望以编程方式关闭窗口。仅仅调用Close()是不行的。这样做:

allowClosing = true;
Close();

#6


8  

I was trying Viachaslau's answer since I like the idea of not removing the button but disabling it, but for some reason it did not always work: the close button was still enabled but no errors whatsoever.

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

This on the other hand always worked (error checking omitted):

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

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

#7


8  

I just add my implementation of Joe White's answer using Interactivity Behavior (you need to reference System.Windows.Interactivity).

我只是使用交互性行为(您需要引用System.Windows.Interactivity)添加了Joe White的答案的实现。

code:

代码:

public class HideCloseButtonOnWindow : 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 WindowInteropHelper(AssociatedObject).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    }
}

usage:

用法:

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

#8


6  

The property to set is => WindowStyle="None"

要设置的属性是=> WindowStyle="None"

<Window x:Class="mdaframework.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Start" Height="350" Width="525" ResizeMode="NoResize"  WindowStartupLocation="CenterScreen" WindowStyle="None">

#9


1  

So, pretty much here is your problem. The close button on the upper right of a window frame is not part of the WPF window, but it belongs to the part of the window frame that is controled by your OS. This means you will have to use Win32 interop to do it.

这就是你的问题。窗口框架右上角的close按钮不是WPF窗口的一部分,而是属于您的操作系统控制的窗口框架的一部分。这意味着您将不得不使用Win32互操作来完成它。

alternativly, you can use the noframe and either provide your own "frame" or have no frame at all.

另外,您可以使用noframe,或者提供您自己的“框架”,或者根本没有框架。

#10


1  

The following is about disabling the close and Maximize/Minimize buttons, it does not actually remove the buttons (but it does remove the menu items!). The buttons on the title bar are drawn in a disabled/grayed state. (I'm not quite ready to take over all the functionality myself ^^)

下面是关于禁用关闭和最大化/最小化按钮,它实际上并没有删除按钮(但是它确实删除了菜单项!)标题栏上的按钮以禁用/灰色状态绘制。(我不准备接管所有的功能自己^ ^)

This is slightly different than Virgoss solution in that it removes the menu items (and the trailing separator, if needed) instead of just disabling them. It differs from Joe Whites solution as it does not disable the entire system menu and so, in my case, I can keep around the Minimize button and icon.

这与Virgoss解决方案稍有不同,因为它删除菜单项(如果需要,还删除尾随分隔符),而不是禁用它们。它与Joe white解决方案不同,因为它不禁用整个系统菜单,所以在我的例子中,我可以保留最小化按钮和图标。

The follow code also supports disabling the Maximize/Minimize buttons as, unlike the Close button, removing the entries from the menu does not cause the system to render the buttons "disabled" even though removing the menu entries does disable the functionality of the buttons.

follow代码还支持禁用最大化/最小化按钮,因为与Close按钮不同,从菜单中删除条目不会导致系统呈现“禁用”按钮,即使删除菜单条目会禁用按钮的功能。

It works for me. YMMV.

它适合我。YMMV。

    using System;
    using System.Collections.Generic;
    using System.Text;

    using System.Runtime.InteropServices;
    using Window = System.Windows.Window;
    using WindowInteropHelper = System.Windows.Interop.WindowInteropHelper;
    using Win32Exception = System.ComponentModel.Win32Exception;

    namespace Channelmatter.Guppy
    {

        public class WindowUtil
        {
            const int MF_BYCOMMAND = 0x0000;
            const int MF_BYPOSITION = 0x0400;

            const uint MFT_SEPARATOR = 0x0800;

            const uint MIIM_FTYPE = 0x0100;

            [DllImport("user32", SetLastError=true)]
            private static extern uint RemoveMenu(IntPtr hMenu, uint nPosition, uint wFlags);

            [DllImport("user32", SetLastError=true)]
            private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

            [DllImport("user32", SetLastError=true)]
            private static extern int GetMenuItemCount(IntPtr hWnd);

            [StructLayout(LayoutKind.Sequential)]
            public struct MenuItemInfo {
                public uint   cbSize;
                public uint   fMask;
                public uint   fType;
                public uint   fState;
                public uint   wID;
                public IntPtr hSubMenu;
                public IntPtr hbmpChecked;
                public IntPtr hbmpUnchecked;
                public IntPtr dwItemData; // ULONG_PTR
                public IntPtr dwTypeData;
                public uint   cch;
                public IntPtr hbmpItem;
            };

            [DllImport("user32", SetLastError=true)]
            private static extern int GetMenuItemInfo(
                IntPtr hMenu, uint uItem,
                bool fByPosition, ref MenuItemInfo itemInfo);

            public enum MenuCommand : uint
            {
                SC_CLOSE = 0xF060,
                SC_MAXIMIZE = 0xF030,
            }

            public static void WithSystemMenu (Window win, Action<IntPtr> action) {
                var interop = new WindowInteropHelper(win);
                IntPtr hMenu = GetSystemMenu(interop.Handle, false);
                if (hMenu == IntPtr.Zero) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get system menu");
                } else {
                    action(hMenu);
                }
            }

            // Removes the menu item for the specific command.
            // This will disable and gray the Close button and disable the
            // functionality behind the Maximize/Minimuze buttons, but it won't
            // gray out the Maximize/Minimize buttons. It will also not stop
            // the default Alt+F4 behavior.
            public static void RemoveMenuItem (Window win, MenuCommand command) {
                WithSystemMenu(win, (hMenu) => {
                    if (RemoveMenu(hMenu, (uint)command, MF_BYCOMMAND) == 0) {
                        throw new Win32Exception(Marshal.GetLastWin32Error(),
                            "Failed to remove menu item");
                    }
                });
            }

            public static bool RemoveTrailingSeparator (Window win) {
                bool result = false; // Func<...> not in .NET3 :-/
                WithSystemMenu(win, (hMenu) => {
                    result = RemoveTrailingSeparator(hMenu);
                });
                return result;
            }

            // Removes the final trailing separator of a menu if it exists.
            // Returns true if a separator is removed.
            public static bool RemoveTrailingSeparator (IntPtr hMenu) {
                int menuItemCount = GetMenuItemCount(hMenu);
                if (menuItemCount < 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get menu item count");
                }
                if (menuItemCount == 0) {
                    return false;
                } else {
                    uint index = (uint)(menuItemCount - 1);
                    MenuItemInfo itemInfo = new MenuItemInfo {
                        cbSize = (uint)Marshal.SizeOf(typeof(MenuItemInfo)),
                        fMask = MIIM_FTYPE,
                    };

                    if (GetMenuItemInfo(hMenu, index, true, ref itemInfo) == 0) {
                        throw new Win32Exception(Marshal.GetLastWin32Error(),
                            "Failed to get menu item info");
                    }

                    if (itemInfo.fType == MFT_SEPARATOR) {
                        if (RemoveMenu(hMenu, index, MF_BYPOSITION) == 0) {
                            throw new Win32Exception(Marshal.GetLastWin32Error(),
                                "Failed to remove menu item");
                        }
                        return true;
                    } else {
                        return false;
                    }
                }
            }

            private const int GWL_STYLE = -16;

            [Flags]
            public enum WindowStyle : int
            {
                WS_MINIMIZEBOX = 0x00020000,
                WS_MAXIMIZEBOX = 0x00010000,
            }

            // Don't use this version for dealing with pointers
            [DllImport("user32", SetLastError=true)]
            private static extern int SetWindowLong (IntPtr hWnd, int nIndex, int dwNewLong);

            // Don't use this version for dealing with pointers
            [DllImport("user32", SetLastError=true)]
            private static extern int GetWindowLong (IntPtr hWnd, int nIndex);

            public static int AlterWindowStyle (Window win,
                WindowStyle orFlags, WindowStyle andNotFlags) 
            {
                var interop = new WindowInteropHelper(win);

                int prevStyle = GetWindowLong(interop.Handle, GWL_STYLE);
                if (prevStyle == 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get window style");
                }

                int newStyle = (prevStyle | (int)orFlags) & ~((int)andNotFlags);
                if (SetWindowLong(interop.Handle, GWL_STYLE, newStyle) == 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to set window style");
                }
                return prevStyle;
            }

            public static int DisableMaximizeButton (Window win) {
                return AlterWindowStyle(win, 0, WindowStyle.WS_MAXIMIZEBOX);
            }
        }
    }

Usage: This must be done AFTER the source is initialized. A good place is to use the SourceInitialized event of the Window:

用法:必须在初始化源之后执行。一个好的地方是使用窗口的SourceInitialized事件:

Window win = ...; /* the Window :-) */
WindowUtil.DisableMaximizeButton(win);
WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_MAXIMIZE);
WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_CLOSE);
while (WindowUtil.RemoveTrailingSeparator(win)) 
{
   //do it here
}

To disable the Alt+F4 functionality the easy method is just to wire up the Canceling event and use set a flag for when you really do want to close the window.

要禁用Alt+F4功能,简单的方法就是将取消事件连接起来,并在需要关闭窗口时使用设置标志。

#11


0  

XAML Code

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>

should work

应该工作

Edit- for your instant this Thread shows how that can be done but I don't think Window has a property to get what you want without losing the normal title bar.

编辑——这个线程显示了如何实现这一点,但是我不认为窗口有一个属性可以在不丢失常规标题栏的情况下获得您想要的内容。

Edit 2 This Thread shows a way for it to be done, but you must apply your own style to the system menu and it shows a way how you can do that.

编辑2这个线程显示了一种方法,但是您必须将您自己的样式应用到系统菜单中,它显示了您如何做到这一点。

#12


0  

Let the user "close" the window but really just hide it.

让用户“关闭”窗口,但实际上只是隐藏它。

In the window's OnClosing event, hide the window if already visible:

在窗口的onclose事件中,如果已经可见,则隐藏窗口:

    If Me.Visibility = Windows.Visibility.Visible Then
        Me.Visibility = Windows.Visibility.Hidden
        e.Cancel = True
    End If

Each time the Background thread is to be executed, re-show background UI window:

每次执行后台线程时,重新显示后台UI窗口:

    w.Visibility = Windows.Visibility.Visible
    w.Show()

When terminating execution of program, make sure all windows are/can-be closed:

在终止程序执行时,请确保所有窗口都已关闭:

Private Sub CloseAll()
    If w IsNot Nothing Then
        w.Visibility = Windows.Visibility.Collapsed ' Tell OnClosing to really close
        w.Close()
    End If
End Sub

#13


0  

goto window properties set

转到窗口属性设置

window style = none;

u wont get close buttons...

你不会得到关闭按钮…

#14


0  

Try adding a Closing event to the window. Add this code to the event handler.

尝试向窗口添加一个关闭事件。将此代码添加到事件处理程序。

e.Cancel = true;

This will prevent the window from closing. This has the same effect as hiding the close button.

这将防止窗口关闭。这与隐藏关闭按钮具有相同的效果。

#15


0  

Use this, modified from https://stephenhaunts.com/2014/09/25/remove-the-close-button-from-a-wpf-window :

使用这个,修改为https://stephenhaunts.com/2014/09/25/remove- close-button-from-a-wpf-window:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;

namespace Whatever
{
    public partial class MainMenu : Window
    {
        private const int GWL_STYLE = -16;
        private const int WS_SYSMENU = 0x00080000;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLongPtr(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        public MainMenu()
        {
             InitializeComponent();
             this.Loaded += new RoutedEventHandler(Window_Loaded);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var hwnd = new WindowInteropHelper(this).Handle;
            SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_SYSMENU);
        }  

    }
}

#16


0  

After much searching for the answer to this, I worked out this simple solution that I will share here in hopes it helps others.

在寻找这个问题的答案之后,我找到了这个简单的解决方案,我将在这里与大家分享,希望它能帮助其他人。

I set WindowStyle=0x10000000.

我把WindowStyle = 0 x10000000。

This sets the WS_VISIBLE (0x10000000) and WS_OVERLAPPED (0x0) values for Window Style. "Overlapped" is the necessary value to show the title bar and window border. By removing the WS_MINIMIZEBOX (0x20000), WS_MAXIMIZEBOX (0x10000), and WS_SYSMENU (0x80000) values from my style value, all the buttons from the title bar were removed, including the Close button.

这将为窗口样式设置WS_VISIBLE (0x10000000)和ws_overlap (0x0)值。“重叠”是显示标题栏和窗口边框的必要值。通过删除ws_最小化框(0x20000)、WS_MAXIMIZEBOX (0x10000)和WS_SYSMENU (0x80000)值,从我的样式值中删除了标题栏的所有按钮,包括关闭按钮。

#17


-1  

As stated in other answers, you can use WindowStyle="None" to remove the Title Bar altogether.

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

And, as stated in the comments to those other answers, this prevents the window from being draggable so it is hard to move it from its initial position.

而且,正如注释中对其他答案所述,这阻止了窗口被拖拽,因此很难将其从初始位置移动。

However, you can overcome this by adding a single line of code to the Constructor in the Window's Code Behind file:

但是,您可以通过在窗口后面的代码中向构造函数添加一行代码来克服这一点:

MouseDown += delegate { DragMove(); };

Or, if you prefer Lambda Syntax:

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

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

This makes the entire Window draggable. Any interactive controls present in the Window, such as Buttons, will still work as normal and won't act as drag-handles for the Window.

这使得整个窗口都是可拖动的。窗口中出现的任何交互控件,如按钮,都将正常工作,并不能充当窗口的拖动句柄。

#18


-2  

Use WindowStyle="SingleBorderWindow" , this will hide max and min button from WPF Window.

使用WindowStyle="SingleBorderWindow",这将隐藏WPF窗口中的max和min按钮。

#19


-2  

If the need is only to prohibit the user from closing the window, this is a simple solution.

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

XAML code: IsCloseButtonEnabled="False"

XAML代码:IsCloseButtonEnabled = " False "

#1


241  

WPF doesn't have a built-in property to hide the title bar's Close button, but you can do it with a few lines of P/Invoke.

WPF没有内置属性来隐藏标题栏的关闭按钮,但是您可以使用几行P/Invoke。

First, add these declarations to your Window class:

首先,将这些声明添加到窗口类:

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

Then put this code in the Window's Loaded event:

然后将此代码放入窗口已加载的事件中:

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

And there you go: no more Close button. You also won't have a window icon on the left side of the title bar, which means no System menu, even when you right-click the title bar -- they all go together.

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

Note that Alt+F4 will still close the Window. If you don't want to allow the window to close before the background thread is done, then you could also override OnClosing and set Cancel to true, as Gabe suggested.

注意,Alt+F4仍然会关闭窗口。如果您不想让窗口在后台线程完成之前关闭,那么您也可以重写onclose并将Cancel设置为true,正如Gabe所建议的那样。

#2


79  

I just got to similar problem and Joe White's solution seems to me simple and clean. I reused it and defined it as an attached property of Window

我刚刚遇到了类似的问题,乔·怀特的解决方案在我看来简单明了。我重新使用它并将它定义为窗口的附加属性

public class WindowBehavior
{
    private static readonly Type OwnerType = typeof (WindowBehavior);

    #region HideCloseButton (attached property)

    public static readonly DependencyProperty HideCloseButtonProperty =
        DependencyProperty.RegisterAttached(
            "HideCloseButton",
            typeof (bool),
            OwnerType,
            new FrameworkPropertyMetadata(false, new PropertyChangedCallback(HideCloseButtonChangedCallback)));

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static bool GetHideCloseButton(Window obj) {
        return (bool)obj.GetValue(HideCloseButtonProperty);
    }

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static void SetHideCloseButton(Window obj, bool value) {
        obj.SetValue(HideCloseButtonProperty, value);
    }

    private static void HideCloseButtonChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var window = d as Window;
        if (window == null) return;

        var hideCloseButton = (bool)e.NewValue;
        if (hideCloseButton && !GetIsHiddenCloseButton(window)) {
            if (!window.IsLoaded) {
                window.Loaded += HideWhenLoadedDelegate;
            }
            else {
                HideCloseButton(window);
            }
            SetIsHiddenCloseButton(window, true);
        }
        else if (!hideCloseButton && GetIsHiddenCloseButton(window)) {
            if (!window.IsLoaded) {
                window.Loaded -= ShowWhenLoadedDelegate;
            }
            else {
                ShowCloseButton(window);
            }
            SetIsHiddenCloseButton(window, false);
        }
    }

    #region Win32 imports

    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

    private static readonly RoutedEventHandler HideWhenLoadedDelegate = (sender, args) => {
        if (sender is Window == false) return;
        var w = (Window)sender;
        HideCloseButton(w);
        w.Loaded -= HideWhenLoadedDelegate;
    };

    private static readonly RoutedEventHandler ShowWhenLoadedDelegate = (sender, args) => {
        if (sender is Window == false) return;
        var w = (Window)sender;
        ShowCloseButton(w);
        w.Loaded -= ShowWhenLoadedDelegate;
    };

    private static void HideCloseButton(Window w) {
        var hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    }

    private static void ShowCloseButton(Window w) {
        var hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_SYSMENU);
    }

    #endregion

    #region IsHiddenCloseButton (readonly attached property)

    private static readonly DependencyPropertyKey IsHiddenCloseButtonKey =
        DependencyProperty.RegisterAttachedReadOnly(
            "IsHiddenCloseButton",
            typeof (bool),
            OwnerType,
            new FrameworkPropertyMetadata(false));

    public static readonly DependencyProperty IsHiddenCloseButtonProperty =
        IsHiddenCloseButtonKey.DependencyProperty;

    [AttachedPropertyBrowsableForType(typeof(Window))]
    public static bool GetIsHiddenCloseButton(Window obj) {
        return (bool)obj.GetValue(IsHiddenCloseButtonProperty);
    }

    private static void SetIsHiddenCloseButton(Window obj, bool value) {
        obj.SetValue(IsHiddenCloseButtonKey, value);
    }

    #endregion

}

Then in XAML you just set it like this:

在XAML中,你只需要这样设置:

<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:u="clr-namespace:WafClient.Presentation.Behaviors"
    ResizeMode="NoResize"
    u:WindowBehavior.HideCloseButton="True">
    ...
</Window>

#3


53  

Set WindowStyle property to None which will hide the control box along with the title bar. No need to kernal calls.

将WindowStyle属性设置为None,该属性将隐藏控件框和标题栏。没有必要打电话。

#4


48  

This won't get rid of the close button, but it will stop someone closing the window.

这不会消除关闭按钮,但它会阻止某人关闭窗口。

Put this in your code behind file:

把这个放在你的代码后面的文件:

protected override void OnClosing(CancelEventArgs e)
{
   base.OnClosing(e);
   e.Cancel = true;
}

#5


15  

To disable close button you should add the following code to your Window class (the code was taken from here, edited and reformatted a bit):

要禁用关闭按钮,您应该向窗口类添加以下代码(代码从这里开始,编辑并重新格式化):

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

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

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

}

private bool allowClosing = false;

[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;
private const int WM_CLOSE = 0x10;

private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case WM_SHOWWINDOW:
            {
                IntPtr hMenu = GetSystemMenu(hwnd, false);
                if (hMenu != IntPtr.Zero)
                {
                    EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
                }
            }
            break;
        case WM_CLOSE:
            if (!allowClosing)
            {
                handled = true;
            }
            break;
    }
    return IntPtr.Zero;
}

This code also disables close item in System menu and disallows closing the dialog using Alt+F4.

此代码还禁止在系统菜单中关闭项,并禁止使用Alt+F4关闭对话框。

You will probably want to close the window programmatically. Just calling Close() will not work. Do something like this:

您可能希望以编程方式关闭窗口。仅仅调用Close()是不行的。这样做:

allowClosing = true;
Close();

#6


8  

I was trying Viachaslau's answer since I like the idea of not removing the button but disabling it, but for some reason it did not always work: the close button was still enabled but no errors whatsoever.

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

This on the other hand always worked (error checking omitted):

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

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

#7


8  

I just add my implementation of Joe White's answer using Interactivity Behavior (you need to reference System.Windows.Interactivity).

我只是使用交互性行为(您需要引用System.Windows.Interactivity)添加了Joe White的答案的实现。

code:

代码:

public class HideCloseButtonOnWindow : 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 WindowInteropHelper(AssociatedObject).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    }
}

usage:

用法:

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

#8


6  

The property to set is => WindowStyle="None"

要设置的属性是=> WindowStyle="None"

<Window x:Class="mdaframework.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Start" Height="350" Width="525" ResizeMode="NoResize"  WindowStartupLocation="CenterScreen" WindowStyle="None">

#9


1  

So, pretty much here is your problem. The close button on the upper right of a window frame is not part of the WPF window, but it belongs to the part of the window frame that is controled by your OS. This means you will have to use Win32 interop to do it.

这就是你的问题。窗口框架右上角的close按钮不是WPF窗口的一部分,而是属于您的操作系统控制的窗口框架的一部分。这意味着您将不得不使用Win32互操作来完成它。

alternativly, you can use the noframe and either provide your own "frame" or have no frame at all.

另外,您可以使用noframe,或者提供您自己的“框架”,或者根本没有框架。

#10


1  

The following is about disabling the close and Maximize/Minimize buttons, it does not actually remove the buttons (but it does remove the menu items!). The buttons on the title bar are drawn in a disabled/grayed state. (I'm not quite ready to take over all the functionality myself ^^)

下面是关于禁用关闭和最大化/最小化按钮,它实际上并没有删除按钮(但是它确实删除了菜单项!)标题栏上的按钮以禁用/灰色状态绘制。(我不准备接管所有的功能自己^ ^)

This is slightly different than Virgoss solution in that it removes the menu items (and the trailing separator, if needed) instead of just disabling them. It differs from Joe Whites solution as it does not disable the entire system menu and so, in my case, I can keep around the Minimize button and icon.

这与Virgoss解决方案稍有不同,因为它删除菜单项(如果需要,还删除尾随分隔符),而不是禁用它们。它与Joe white解决方案不同,因为它不禁用整个系统菜单,所以在我的例子中,我可以保留最小化按钮和图标。

The follow code also supports disabling the Maximize/Minimize buttons as, unlike the Close button, removing the entries from the menu does not cause the system to render the buttons "disabled" even though removing the menu entries does disable the functionality of the buttons.

follow代码还支持禁用最大化/最小化按钮,因为与Close按钮不同,从菜单中删除条目不会导致系统呈现“禁用”按钮,即使删除菜单条目会禁用按钮的功能。

It works for me. YMMV.

它适合我。YMMV。

    using System;
    using System.Collections.Generic;
    using System.Text;

    using System.Runtime.InteropServices;
    using Window = System.Windows.Window;
    using WindowInteropHelper = System.Windows.Interop.WindowInteropHelper;
    using Win32Exception = System.ComponentModel.Win32Exception;

    namespace Channelmatter.Guppy
    {

        public class WindowUtil
        {
            const int MF_BYCOMMAND = 0x0000;
            const int MF_BYPOSITION = 0x0400;

            const uint MFT_SEPARATOR = 0x0800;

            const uint MIIM_FTYPE = 0x0100;

            [DllImport("user32", SetLastError=true)]
            private static extern uint RemoveMenu(IntPtr hMenu, uint nPosition, uint wFlags);

            [DllImport("user32", SetLastError=true)]
            private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

            [DllImport("user32", SetLastError=true)]
            private static extern int GetMenuItemCount(IntPtr hWnd);

            [StructLayout(LayoutKind.Sequential)]
            public struct MenuItemInfo {
                public uint   cbSize;
                public uint   fMask;
                public uint   fType;
                public uint   fState;
                public uint   wID;
                public IntPtr hSubMenu;
                public IntPtr hbmpChecked;
                public IntPtr hbmpUnchecked;
                public IntPtr dwItemData; // ULONG_PTR
                public IntPtr dwTypeData;
                public uint   cch;
                public IntPtr hbmpItem;
            };

            [DllImport("user32", SetLastError=true)]
            private static extern int GetMenuItemInfo(
                IntPtr hMenu, uint uItem,
                bool fByPosition, ref MenuItemInfo itemInfo);

            public enum MenuCommand : uint
            {
                SC_CLOSE = 0xF060,
                SC_MAXIMIZE = 0xF030,
            }

            public static void WithSystemMenu (Window win, Action<IntPtr> action) {
                var interop = new WindowInteropHelper(win);
                IntPtr hMenu = GetSystemMenu(interop.Handle, false);
                if (hMenu == IntPtr.Zero) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get system menu");
                } else {
                    action(hMenu);
                }
            }

            // Removes the menu item for the specific command.
            // This will disable and gray the Close button and disable the
            // functionality behind the Maximize/Minimuze buttons, but it won't
            // gray out the Maximize/Minimize buttons. It will also not stop
            // the default Alt+F4 behavior.
            public static void RemoveMenuItem (Window win, MenuCommand command) {
                WithSystemMenu(win, (hMenu) => {
                    if (RemoveMenu(hMenu, (uint)command, MF_BYCOMMAND) == 0) {
                        throw new Win32Exception(Marshal.GetLastWin32Error(),
                            "Failed to remove menu item");
                    }
                });
            }

            public static bool RemoveTrailingSeparator (Window win) {
                bool result = false; // Func<...> not in .NET3 :-/
                WithSystemMenu(win, (hMenu) => {
                    result = RemoveTrailingSeparator(hMenu);
                });
                return result;
            }

            // Removes the final trailing separator of a menu if it exists.
            // Returns true if a separator is removed.
            public static bool RemoveTrailingSeparator (IntPtr hMenu) {
                int menuItemCount = GetMenuItemCount(hMenu);
                if (menuItemCount < 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get menu item count");
                }
                if (menuItemCount == 0) {
                    return false;
                } else {
                    uint index = (uint)(menuItemCount - 1);
                    MenuItemInfo itemInfo = new MenuItemInfo {
                        cbSize = (uint)Marshal.SizeOf(typeof(MenuItemInfo)),
                        fMask = MIIM_FTYPE,
                    };

                    if (GetMenuItemInfo(hMenu, index, true, ref itemInfo) == 0) {
                        throw new Win32Exception(Marshal.GetLastWin32Error(),
                            "Failed to get menu item info");
                    }

                    if (itemInfo.fType == MFT_SEPARATOR) {
                        if (RemoveMenu(hMenu, index, MF_BYPOSITION) == 0) {
                            throw new Win32Exception(Marshal.GetLastWin32Error(),
                                "Failed to remove menu item");
                        }
                        return true;
                    } else {
                        return false;
                    }
                }
            }

            private const int GWL_STYLE = -16;

            [Flags]
            public enum WindowStyle : int
            {
                WS_MINIMIZEBOX = 0x00020000,
                WS_MAXIMIZEBOX = 0x00010000,
            }

            // Don't use this version for dealing with pointers
            [DllImport("user32", SetLastError=true)]
            private static extern int SetWindowLong (IntPtr hWnd, int nIndex, int dwNewLong);

            // Don't use this version for dealing with pointers
            [DllImport("user32", SetLastError=true)]
            private static extern int GetWindowLong (IntPtr hWnd, int nIndex);

            public static int AlterWindowStyle (Window win,
                WindowStyle orFlags, WindowStyle andNotFlags) 
            {
                var interop = new WindowInteropHelper(win);

                int prevStyle = GetWindowLong(interop.Handle, GWL_STYLE);
                if (prevStyle == 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to get window style");
                }

                int newStyle = (prevStyle | (int)orFlags) & ~((int)andNotFlags);
                if (SetWindowLong(interop.Handle, GWL_STYLE, newStyle) == 0) {
                    throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Failed to set window style");
                }
                return prevStyle;
            }

            public static int DisableMaximizeButton (Window win) {
                return AlterWindowStyle(win, 0, WindowStyle.WS_MAXIMIZEBOX);
            }
        }
    }

Usage: This must be done AFTER the source is initialized. A good place is to use the SourceInitialized event of the Window:

用法:必须在初始化源之后执行。一个好的地方是使用窗口的SourceInitialized事件:

Window win = ...; /* the Window :-) */
WindowUtil.DisableMaximizeButton(win);
WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_MAXIMIZE);
WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_CLOSE);
while (WindowUtil.RemoveTrailingSeparator(win)) 
{
   //do it here
}

To disable the Alt+F4 functionality the easy method is just to wire up the Canceling event and use set a flag for when you really do want to close the window.

要禁用Alt+F4功能,简单的方法就是将取消事件连接起来,并在需要关闭窗口时使用设置标志。

#11


0  

XAML Code

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>

should work

应该工作

Edit- for your instant this Thread shows how that can be done but I don't think Window has a property to get what you want without losing the normal title bar.

编辑——这个线程显示了如何实现这一点,但是我不认为窗口有一个属性可以在不丢失常规标题栏的情况下获得您想要的内容。

Edit 2 This Thread shows a way for it to be done, but you must apply your own style to the system menu and it shows a way how you can do that.

编辑2这个线程显示了一种方法,但是您必须将您自己的样式应用到系统菜单中,它显示了您如何做到这一点。

#12


0  

Let the user "close" the window but really just hide it.

让用户“关闭”窗口,但实际上只是隐藏它。

In the window's OnClosing event, hide the window if already visible:

在窗口的onclose事件中,如果已经可见,则隐藏窗口:

    If Me.Visibility = Windows.Visibility.Visible Then
        Me.Visibility = Windows.Visibility.Hidden
        e.Cancel = True
    End If

Each time the Background thread is to be executed, re-show background UI window:

每次执行后台线程时,重新显示后台UI窗口:

    w.Visibility = Windows.Visibility.Visible
    w.Show()

When terminating execution of program, make sure all windows are/can-be closed:

在终止程序执行时,请确保所有窗口都已关闭:

Private Sub CloseAll()
    If w IsNot Nothing Then
        w.Visibility = Windows.Visibility.Collapsed ' Tell OnClosing to really close
        w.Close()
    End If
End Sub

#13


0  

goto window properties set

转到窗口属性设置

window style = none;

u wont get close buttons...

你不会得到关闭按钮…

#14


0  

Try adding a Closing event to the window. Add this code to the event handler.

尝试向窗口添加一个关闭事件。将此代码添加到事件处理程序。

e.Cancel = true;

This will prevent the window from closing. This has the same effect as hiding the close button.

这将防止窗口关闭。这与隐藏关闭按钮具有相同的效果。

#15


0  

Use this, modified from https://stephenhaunts.com/2014/09/25/remove-the-close-button-from-a-wpf-window :

使用这个,修改为https://stephenhaunts.com/2014/09/25/remove- close-button-from-a-wpf-window:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;

namespace Whatever
{
    public partial class MainMenu : Window
    {
        private const int GWL_STYLE = -16;
        private const int WS_SYSMENU = 0x00080000;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLongPtr(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        public MainMenu()
        {
             InitializeComponent();
             this.Loaded += new RoutedEventHandler(Window_Loaded);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var hwnd = new WindowInteropHelper(this).Handle;
            SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_SYSMENU);
        }  

    }
}

#16


0  

After much searching for the answer to this, I worked out this simple solution that I will share here in hopes it helps others.

在寻找这个问题的答案之后,我找到了这个简单的解决方案,我将在这里与大家分享,希望它能帮助其他人。

I set WindowStyle=0x10000000.

我把WindowStyle = 0 x10000000。

This sets the WS_VISIBLE (0x10000000) and WS_OVERLAPPED (0x0) values for Window Style. "Overlapped" is the necessary value to show the title bar and window border. By removing the WS_MINIMIZEBOX (0x20000), WS_MAXIMIZEBOX (0x10000), and WS_SYSMENU (0x80000) values from my style value, all the buttons from the title bar were removed, including the Close button.

这将为窗口样式设置WS_VISIBLE (0x10000000)和ws_overlap (0x0)值。“重叠”是显示标题栏和窗口边框的必要值。通过删除ws_最小化框(0x20000)、WS_MAXIMIZEBOX (0x10000)和WS_SYSMENU (0x80000)值,从我的样式值中删除了标题栏的所有按钮,包括关闭按钮。

#17


-1  

As stated in other answers, you can use WindowStyle="None" to remove the Title Bar altogether.

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

And, as stated in the comments to those other answers, this prevents the window from being draggable so it is hard to move it from its initial position.

而且,正如注释中对其他答案所述,这阻止了窗口被拖拽,因此很难将其从初始位置移动。

However, you can overcome this by adding a single line of code to the Constructor in the Window's Code Behind file:

但是,您可以通过在窗口后面的代码中向构造函数添加一行代码来克服这一点:

MouseDown += delegate { DragMove(); };

Or, if you prefer Lambda Syntax:

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

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

This makes the entire Window draggable. Any interactive controls present in the Window, such as Buttons, will still work as normal and won't act as drag-handles for the Window.

这使得整个窗口都是可拖动的。窗口中出现的任何交互控件,如按钮,都将正常工作,并不能充当窗口的拖动句柄。

#18


-2  

Use WindowStyle="SingleBorderWindow" , this will hide max and min button from WPF Window.

使用WindowStyle="SingleBorderWindow",这将隐藏WPF窗口中的max和min按钮。

#19


-2  

If the need is only to prohibit the user from closing the window, this is a simple solution.

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

XAML code: IsCloseButtonEnabled="False"

XAML代码:IsCloseButtonEnabled = " False "