WPFウィンドウで閉じるボタンを非表示にする方法は?


204

WPFでモーダルダイアログを作成しています。閉じるボタンがないようにWPFウィンドウを設定するにはどうすればよいですか?それでもWindowState通常のタイトルバーが欲しいです。

私が見つかりましたResizeModeWindowStateWindowStyle、しかし、これらのプロパティのどれもがモーダルダイアログのように、私は閉じるボタンを非表示にしますが、タイトルバーを表示することができません。


9
これは、キャンセルをサポートしないバックグラウンドスレッドを実行している進行状況ダイアログです。(まだ)キャンセルをサポートする必要がないように、私はそれを作ろうとしているだけだと思います。あなたはおそらく正しいです。
マイケル・ヘドペス2009

1
また、ウィンドウクロームを削除しようとするアプリも嫌いです。進行状況ダイアログを作成する場合、ウィンドウの[閉じる]ボタンには、実際の[キャンセル]ボタンをクリックするのと同じロジックを常に実行させます。
クリスチャンヘイター2010

13
Chrisの場合:ソフトウェアがビデオ監視用であることを想像してみてください。夜間のセキュリティエージェントはウィンドウを開いたままにしておく必要があります(それが彼の仕事です)。それをするために。
Jean-Marie

7
@ChrisUpchurch、「なぜこれをしたいのですか?本当にお粗末なUIデザインだと思います。」 -本当に「お粗末なUIデザイン」とは、プログラムがOKのダイアログボックスを表示するときです[キャンセル]ボタンと[閉じる]ボタン。ユーザーにとって、Closeが何をするのかは明らかではないかもしれません。それはありませんキャンセルまたは提出しますかコンセンサスはダイアログに閉じるボタンを含めることではないので、それがあります
MickyD

1
@ Jean-Marieしかし、閉じるボタンを非表示にしても、それが発生するのを防ぐことはできません。これは、無知で怠惰な(Googleに対して)騙すだけです。閉じるボタンを非表示にしても、そのボタンをクリックすることはできません。WinキーとAltキーの組み合わせは通常どおり機能します。「適切な」方法は、承認されたもの以外のソフトウェアを開いたりインストールしたりできないようにするグループポリシーを使用して、ワーカーのユーザーアカウントを作成することです。次に、スーパーバイザがアクセスできる管理アカウントで、メンテナンスを処理します。
Digital_Utopia

回答:


275

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

次に、このコードをウィンドウのLoadedイベントに配置します。

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

これで、閉じるボタンはなくなりました。また、タイトルバーの左側にウィンドウアイコンは表示されません。つまり、タイトルバーを右クリックしても、システムメニューはありません。これらはすべて一緒になっています。

なお、Alt+ F4意志まだウィンドウを閉じます。Gabeが示唆するように、バックグラウンドスレッドが完了する前にウィンドウを閉じたくない場合は、オーバーライドOnClosingCancelてtrueに設定することもできます。


5
ドキュメントによると、SetWindowLongPtr代わりに使用する必要があります。
ジョナサンアレン

15
主に自己へのメモ... DllImportの名前空間-> System.Runtime.InteropServices.DllImport。WindowInteropHelperの名前空間-> System.Windows.Interop.WindowInteropHelper
doobop

3
実際、このアプローチでは3つのボタン(最小、最大、閉じる)がすべて非表示になります。閉じるボタンを非表示にすることはできますか?
ニューマン

4
@miliu、いや。あなたはできるそれを無効にしますが、同様の隠蔽の最小化/最大化することなく、それを隠すことはできません。Windows開発者は、Maximizeが通常Closeの右側にあると混乱を招くと思ったのではないかと思います。
ジョーホワイト

3
XAMLファイルのWindowタグにWindowStyle = "None"を配置します。
diegodsp 2015

88

私は同様の問題にたどり着きましたが、ジョーホワイトの解決策は私にはシンプルでクリーンなようです。私はそれを再利用し、ウィンドウの添付プロパティとして定義しました

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

}

次に、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>

63

WindowStyleプロパティをNoneに設定すると、タイトルボックスと共にコントロールボックスが非表示になります。カーネルコールの必要はありません。


20
まあ、これはウィンドウのタイトルバーを完全に隠します。つまり、ウィンドウのタイトルを取得できず、ユーザーはウィンドウを移動できなくなります。
ニューマン2013年

7
this.DragMove();ウィンドウのMouseDownイベントに追加することにより、ウィンドウを移動可能にすることができます
ポール

1
開かれた古いスキーマを使用したデータベースのアップグレードの進捗状況など、純粋に情報提供と必須のモーダルダイアログの場合、このソリューションは最適です。
Lonely Coder

1
国境が欲しい人もいると思いますが
pjdupreez

2
間違いなく最高のソリューション。パネルに境界線を追加したり、移動を実装したりしても問題はありません。
2017

50

これは閉じるボタンを取り除きませんが、誰かがウィンドウを閉じるのを止めます。

これをコードビハインドファイルに入れます。

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

7
Windowモーダルダイアログとして設定されているでこれを行うと、プロパティのWindow設定に干渉し、DialogResult使用できなくなる場合があることに注意してください。stackoverflow.com/questions/898708/cant-set-dialogresult-in-wpf
シェリダン

4
私はこのメソッドを使用してオーバーフローを取得していました、私はbase.OnClosing(e)を取り出し、それが機能しました
jacobsgriffith

8
ユーザーとして、これをアプリケーションに
組み込ん

2
@UrbanEsc私はそうするのが面倒なことに同意する傾向がありますが、これを行ったとき-そしてそれが一度だけ-それは必須の要件であり、それは必要な悪であり、いくつかの非常に重要なプロセスが起こっていましたこれは中断できず、完了するまでアプリを続行できませんでした。他の方法(バックグラウンドスレッド、準備ができるまでUIが無効になっているスレッド)もありましたが、プロセスの重要性を強調するため、ボスとクライアントの両方がこの方法を好んでいました。
フルビウス2017

15

閉じるボタンを無効にするには、次のコードをWindowクラスに追加する必要があります(コードはここから取得され、少し編集および再フォーマットされています)。

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

このコードは、システムメニューの閉じる項目を無効にし、Alt + F4を使用してダイアログを閉じることもできません。

プログラムでウィンドウを閉じることをお勧めします。電話をかけるだけでClose()は機能しません。このようなことをしてください:

allowClosing = true;
Close();

Windows 7の場合:上記により、ドロップダウンの[システム]メニューの[閉じる]項目も無効になります(ただし、削除はされません)。[閉じる]ボタン自体は無効(灰色に見えます)ですが、削除されていません。このトリックは、最小化/最大化のアイテム/ボタンでは機能しません-WPFがそれらを再度有効にするのではないかと思います。

3
ボタンを無効にすることは、ボタンを削除するだけではなく、重要な操作が実行されていることをユーザーに通知しながら、一貫した感覚を維持します。
ロバートベイカー、

10

ボタンを削除せずに無効にするというアイデアが好きだったので、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 );
}

1
パーフェクト!Windowプロジェクトに拡張メソッドとして追加されました。
Matt Davis

8

設定するプロパティは=> 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">

4
これにより、最大/最小ボタンも非表示になります
VoteCoffee

3
タイトルバー全体が削除され、ボックスが見苦しく、説明なしで表示されます。Shotgunアプローチと重複回答。反対票。
vapcguy 2017年

これは、常にアプリケーションを最大化する必要があり、顧客がアプリを閉じることができないようなキオスクアプリケーションに最適なソリューションです。So UpVote
Rajon Tanducar

8

対話性動作を使用して、ジョーホワイトの回答の実装を追加するだけです(System.Windows.Interactivityを参照する必要があります)。

コード:

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

使用法:

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

2

ユーザーがウィンドウを「閉じる」ことができるようにしますが、実際には単に非表示にします。

ウィンドウのOnClosingイベントで、既に表示されている場合はウィンドウを非表示にします。

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

バックグラウンドスレッドが実行されるたびに、バックグラウンドUIウィンドウを再表示します。

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

プログラムの実行を終了するときは、すべてのウィンドウが閉じているか、または閉じることができることを確認してください。

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

1

だから、ほとんどここにあなたの問題があります。ウィンドウフレームの右上にある閉じるボタンは、WPFウィンドウの一部ではありませんが、OSによって制御されるウィンドウフレームの一部に属しています。つまり、Win32相互運用機能を使用する必要があります。

代わりに、noframeを使用して、独自の「フレーム」を提供するか、フレームをまったく使用しないこともできます。


1

以下は閉じるボタンと最大化/最小化ボタンの無効化に関するもので、実際にはボタンは削除されませ(ただし、メニュー項目は削除されます!)。タイトルバーのボタンは、無効/グレーの状態で描画されます。(私は自分ですべての機能を引き継ぐ準備ができていません^^)

これは、メニュー項目を無効にするだけでなく、メニュー項目(および必要に応じて末尾のセパレータ)を削除するという点で、Virgossソリューションとは少し異なります。システムメニュー全体を無効にしないため、Joe Whitesのソリューションとは異なります。私の場合は、[最小化]ボタンとアイコンをそのまま使用できます。

次のコードは、最大化/最小化ボタンの無効化もサポートしています。閉じるボタンとは異なり、メニューからエントリを削除しても、メニューエントリを削除してもボタンの機能無効になってても、システムはボタンを「無効」にレンダリングしません。

わたしにはできる。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);
            }
        }
    }

使用法:これは、ソースが初期化された後に実行する必要があります。良い場所は、ウィンドウの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
}

Alt + F4機能を無効にする簡単な方法は、Cancelingイベントを結び付け、本当にウィンドウを閉じたいときにフラグを設定することです。


0

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 このスレッドはそれを行う方法を示していますが、システムメニューに独自のスタイルを適用する必要があり、それを行う方法を示しています。


何らかの理由で「
正常に機能する

3
タイトルバーにあるウィンドウの状態について話しています。これは単純なボタンを編集しているように見えます。
マイケル・ヘドペス2009

@TStamper、私はあなたのスニペットをどのように使用しますか?グローバルウィンドウスタイル(およびテンプレート)を使用しています。
Shimmy Weitzhandler、2010年

@シミー-あなたはどちらを参照していますか?
TStamper

0

ウィンドウにClosingイベントを追加してみてください。このコードをイベントハンドラーに追加します。

e.Cancel = true;

これにより、ウィンドウが閉じなくなります。これには、閉じるボタンを非表示にするのと同じ効果があります。


1
「これは閉じるボタンを隠すのと同じ効果があります。」ただし、ボタンは引き続き表示され、クリック可能です。つまり、ボタンをクリックすると、アニメーション化されて視覚的に押し下げられます。これは、POLAに反するものです。
rory.ap 2016

0

これを使用して、https//stephenhaunts.com/2014/09/25/remove-the-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);
        }  

    }
}

0

これによってボタンが非表示になることはありませんが、ユーザーがウィンドウをシャットダウンして前に進むことができなくなります。

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{            
    if (e.Cancel == false)
    {
        Application.Current.Shutdown();
    }
}

-1

gotoウィンドウプロパティセット

window style = none;

あなたは閉じるボタンを取得しません...


反対票。それは実際ですWindowStyle = "None"-あなたの構文を見てください。別の方法として、これはショットバーアプローチであり、タイトルバーも削除し、ボックスを醜くし、タイトルを付けません。これを処理する方法が非常に多く(他の回答で証明されているように)あり、重複した回答である場合。
vapcguy 2017年

-1

他の回答で述べたように、を使用WindowStyle="None"してタイトルバーを完全に削除できます。

そして、他の回答へのコメントで述べたように、これはウィンドウがドラッグ可能になるのを防ぎ、最初の位置から移動するのが困難になります。

ただし、ウィンドウの分離コードファイルのコンストラクターに1行のコードを追加することで、これを克服できます。

MouseDown += delegate { DragMove(); };

または、Lambda構文を使用する場合:

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

これにより、ウィンドウ全体がドラッグ可能になります。ボタンなど、ウィンドウに存在するインタラクティブコントロールは通常どおり機能し、ウィンドウのドラッグハンドルとして機能しません。


まだ悪い考えです。タイトルバー全体を削除してショットガンアプローチにし、ボックスを醜く見せ、タイトル/説明がないことを意味します。より良い代替案があります。
vapcguy 2017年

@vapcguyタイトルバー全体を削除します。それはショットガンアプローチです。ボックスを醜く見せますか?あなたの意見。はるかに良い代替案は?おそらくあなたのために。みんなのためではありません。:-)
Holf 2017

-1

これに対する答えを多く探した後、他の人の役に立つことを願ってここで共有するこの簡単な解決策を考え出しました。

設定しWindowStyle=0x10000000ます。

これにより、ウィンドウスタイルのWS_VISIBLE (0x10000000)およびWS_OVERLAPPED (0x0)値が設定されます。「オーバーラップ」は、タイトルバーとウィンドウの境界を表示するために必要な値です。除去することによりWS_MINIMIZEBOX (0x20000)WS_MAXIMIZEBOX (0x10000)、とWS_SYSMENU (0x80000)自分のスタイル値からの値は、タイトルバーのすべてのボタンは、[閉じる]ボタンを含め、削除されました。


WPFにWindowStyleは列挙型があり、その値はWindows API定数と一致しません。値をWindowStyle列挙型に強制することはできません。確かに、私はILSpyで.NETソースコードをチェックしました。enum値はプライベート関数CreateWindowStyleでWindows APIに変換され、関数が不明なWindowStyle値を検出した場合は、単に適用されますWindowStyle.None。(唯一の方法は、内部プロパティ_Style_StyleEx使用してリフレクションを使用することです。これはお勧めしません。)
Mike Rosoft

-2

を使用するとWindowStyle="SingleBorderWindow"、WPFウィンドウから最大ボタンと最小ボタンが非表示になります。


1
closeボタンを非表示にする問題を解決しない
夢の記憶

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.