Как сделать окно неактивным wpf

Обновлено: 27.03.2024

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.

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.

It's a progress dialog running a background thread that doesn't support cancelling; I guess I'm just trying to make it so I don't have to support cancelling (yet). You're probably right, though.

I also hate apps trying to remove window chrome. If I make a progress dialog, I always make the window Close button do the same logic as clicking the actual Cancel button.

For Chris: Lets imagine your software is for Video Surveillance. A security Agent during the night HAS (that's his job) to keep the windows opened. but sometimes their work is boring and they want to surf Internet or close the Video Matrices windows for any reason, removing the windows buttons is the proper way to do it.

@ChrisUpchurch, "Why do you want to do this? It strikes me as really lousy UI design. " - really "lousy UI design" is when a program presents a dialog box with OK; Cancel and Close buttons. To a user, it may not be obvious what Close does. Does it cancel or submit? Consensus is not to include close buttons in dialogs so there is that

@Jean-Marie But hiding the close button doesn't prevent that from happening, it only fools the uninformed and lazy(to Google). Hiding the close button only prevents clicking that button. Win key and alt key combos will still work as normal The "proper" way to do it, is to make a user account for workers, with a group policy that prevents them from opening/installing any software other than what's approved.Then have an admin account, that supervisors have access to, to handle any maintenance.

22 Answers 22

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.

First, add these declarations to your Window class:

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

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.

Important note: all this does is hide the button. The user can still close the window! If the user presses Alt + F4 , or closes the app via the taskbar, the window will still close.

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.

Actually, this approach hides all three buttons (Min, Max and Close). Is it possible to just hide the Close button?

@miliu, nope. You can disable it, but you can't hide it without hiding Minimize/Maximize as well. I suspect the Windows devs thought it would be confusing if Maximize was on the right where Close usually is.

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

Then in XAML you just set it like this:

Should it be window.Loaded += ShowWhenLoadedDelegate; instead of -= ? Otherwise I don't see anywhere that ShowWhenLoadedDelegate could ever be called.

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

Well, this will hide the window title bar completely. That means you don't get window title and user will not be able to move the window.

For a modal dialog that should be purely informational and mandatory, like progress on upgrading a database with an old schema that has been opened, this solution is perfect.

Definitely the best solution. There is no problem with adding border to panel, or implementing moving.

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

Put this in your code behind file:

@UrbanEsc I would tend to agree that its an annoying thing to do, but when I did this - and it was only the one time - it was a mandatory requirement, and it was a necessary evil, there was some very important process going on that could not be interrupted and the app couldn't proceed until it was done. There were other ways it could have been done (a background thread, with the UI disabled until ready) but the boss and client both liked it this way because it emphasised the gravity of the process.

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

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

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

In Windows 7: The above also disables (but does not remove) the Close item in the drop-down System menu. The Close button itself is disable (looks gray), but not removed. This trick does not work for the Minimize/Maximize item/button -- I suspect WPF re-enables them.

Disabling the button is better than just removing them, it keeps a consistent feel while letting the user know that an important operation is running.

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.

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

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

It removes the whole title bar, rendering the box ugly and without a description. Shotgun approach and a duplicate answer. Downvote.

This is the best solution for kiosk applications which always need its application to be maximized and shouldn't allow customers to close app. So UpVote

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

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

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

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

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

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.

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

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.

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.

It works for me. YMMV.

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

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 .
  • Нажатие кнопки Закрыть.
  • Нажатие клавиши ESC , если свойство кнопки IsCancel имеет значение true в модальном окне.

При проектировании окна предоставьте дополнительные механизмы для закрытия окна в клиентской области. Вот некоторые из общих элементов дизайна окна, которые используются для его закрытия:

  • Элемент Выход в меню Файл, обычно для главных окон приложений.
  • Элемент Закрыть в меню Файл, как правило, применим для вторичных окон приложений.
  • Кнопка Отменить, обычно для модального диалогового окна.
  • Кнопка Закрыть, обычно для немодального диалогового окна.

После закрытия окна один и тот же экземпляр объекта нельзя использовать для повторного открытия окна.

Дополнительные сведения о жизненном цикле окна см. в разделе Общие сведения о окнах WPF: время существования окна.

Закрытие модального окна

При закрытии окна, открытого с помощью ShowDialog метода, задайте DialogResult для true свойства значение или false , чтобы указать состояние "принято" или "отменено" соответственно. Как только DialogResult свойство будет установлено в значение, окно закроется. Следующий код демонстрирует задание DialogResult Свойства:

Также можно вызвать Close метод. Close Если используется метод, DialogResult свойство устанавливается в false значение.

После закрытия окна его нельзя открыть повторно с тем же экземпляром объекта. При попытке отобразить одно и то же окно InvalidOperationException создается исключение. Вместо этого создайте новый экземпляр окна и откройте его.

Закрытие немодального окна

При закрытии окна, открытого с Show помощью метода, используйте Close метод. В следующем примере кода демонстрируется закрытие немодального окна:

Закрыть с помощью "Cancel"

Button.IsCancelСвойство можно установить true в значение, чтобы включить клавишу ESC для автоматического закрытия окна. Работает только при открытии окна с помощью ShowDialog метода.

Скрытие окна

Вместо закрытия окна можно скрыть окно с помощью Hide метода. Скрытое окно можно открыть повторно, в отличие от закрытого окна. Если вы собираетесь повторно использовать экземпляр объекта окна, Скройте окно, а не закрывая его. В следующем примере кода демонстрируется скрытие окна:

Отменить закрытие и скрытие

Если вы разработали кнопки, чтобы скрыть окно, а не закрывать его, пользователь по-прежнему может обойти это и закрыть окно. Элемент Закрыть в системном меню и кнопка Закрыть неклиентской области окна закроет окно, а не будет скрывать его. Рассмотрим этот сценарий, если вам нужно скрыть окно, а не закрывать его.

Если окно отображается модально с ShowDialog , свойство будет установлено в null значение, DialogResult когда окно скрыто. Необходимо передать состояние обратно вызывающему коду, добавив собственное свойство в окно.

Когда окно закрывается, Closing возникает событие. Обработчик передается CancelEventArgs , который реализует Cancel свойство. Задайте для этого свойства true значение, чтобы запретить закрытие окна. В следующем примере кода показано, как отменить закрытие, а не скрыть окно:

Иногда не нужно скрывать окно, но на самом деле запрещает пользователю его закрыть. Дополнительные сведения см. в разделе Общие сведения о окнах WPF: отмена закрытия окна.

In this article, you'll learn about the different ways to close a window or dialog box. A user can close a window by using the elements in the non-client area, including the following:

  • The Close item of the System menu.
  • Pressing ALT + F4 .
  • Pressing the Close button.
  • Pressing ESC when a button has the IsCancel property set to true on a modal window.

When designing a window, provide more mechanisms to the client area to close a window. Some of the common design elements on a window that are used to close it include the following:

  • An Exit item in the File menu, typically for main application windows.
  • A Close item in the File menu, typically on a secondary application window.
  • A Cancel button, typically on a modal dialog box.
  • A Close button, typically on a modeless dialog box.

Once a window is closed, the same object instance can't be used to reopen the window.

For more information about the life of a window, see Overview of WPF windows: Window lifetime.

Close a modal window

When closing a window that was opened with the ShowDialog method, set the DialogResult property to either true or false to indicate an "accepted" or "canceled" state, respectively. As soon as the DialogResult property is set to a value, the window closes. The following code demonstrates setting the DialogResult property:

You can also call the Close method. If the Close method is used, the DialogResult property is set to false .

Once a window has been closed, it can't be reopened with the same object instance. If you try to show the same window, a InvalidOperationException is thrown. Instead, create a new instance of the window and open it.

Close a modeless window

When closing a window that was opened with the Show method, use the Close method. The following code demonstrates closing a modeless window:

Close with IsCancel

The Button.IsCancel property can be set to true to enable the ESC key to automatically close the window. This only works when the window is opened with ShowDialog method.

Hide a window

Instead of closing a window, a window can be hidden with the Hide method. A hidden window can be reopened, unlike a window that has been closed. If you're going to reuse a window object instance, hide the window instead of closing it. The following code demonstrates hiding a window:

Cancel close and hide

If you've designed your buttons to hide a window instead of closing it, the user can still bypass this and close the window. The Close item of the system menu and the Close button of the non-client area of the window, will close the window instead of hiding it. Consider this scenario when your intent is to hide a window instead of closing it.

If a window is shown modally with ShowDialog, the DialogResult property will be set to null when the window is hidden. You'll need to communicate state back to the calling code by adding your own property to the window.

When a window is closed, the Closing event is raised. The handler is passed a CancelEventArgs, which implements the Cancel property. Set that property to true to prevent a window from closing. The following code demonstrates how to cancel the closure and instead hide the window:

There may be times where you don't want to hide a window, but actually prevent the user from closing it. For more information, see Overview of WPF windows: Cancel window closure.

I have a Button that closes my window when it's clicked:

That's fine until I add a Command to the Button i.e.

Now it doesn't close presumably because I am handling the Command . I can fix this by putting an EventHandler in and calling this.Close() i.e.

but now I have code in my code behind i.e. the method SaveCommand . I am using the MVVM pattern and SaveCommand is the only code in my code behind.

How can I do this differently so as not to use code behind?

22 Answers 22

I just completed a blog post on this very topic. In a nutshell, add an Action property to your ViewModel with get and set accessors. Then define the Action from your View constructor. Finally, invoke your action in the bound command that should close the window.

In the ViewModel:

and in the View constructor:

Finally, in whatever bound command that should close the window, we can simply invoke

This worked for me, seemed like a fairly elegant solution, and saved me a bunch of coding.

This doesn't work for me. When I call the CloseAction(), it says that CloseAction is null, despite of the code in the View

Excuse my ignorance but how doesn't this violate the principal of decoupling the View and the ViewModel? If you are instantiating your ViewModel in your View, you may as well not use MVVM. I think best practice is to instantiate your View and ViewModel individually and set the DataContext to the View outside the view itself.

I realize this is getting old, but I would argue that this method doesn't break MVVM unless there is a strict definition I am not aware. Ultimately, MVVM requires that the VM is unaware of the view but the view must be aware of the VM. If one was to replace the view, it wouldn't break the VM in any kind of way. There would be an uninstantiated Action, but I don't think that's a declaration of MVVM rules being broken. Searching for "WPF DataContext Instantiation" will bring up this very method in many articles.

Very clean and MVVM way is to use InteractionTrigger and CallMethodAction defined in Microsoft.Interactivity.Core

You will need to add a new namespace as below

You will need the Microsoft.Xmal.Behaviours.Wpf assembly and then the below xaml code will work.

You don't need any code behind or anything else and can also call any other method of Window .

This is the cleanest approach I've seen so far in terms of no code behind and no coupling the ViewModel to the View. It works with commands too. You will need to deploy a couple of extra DLLs, and would need extra work if you wanted to be able to cancel the close from within your command. It's not a lot different to having a Click event in the code behind and just calling Close(), the code behind event handler would make it easier to handle the scenario of the close command cancelling the close event (e.g. if there was an error saving data). Thanks Massimiliano

It is cleaner, but it's something that I believe should be controlled by the view model, not the view, since it belongs to a command, not to the standard close button.

This only works if you always want to close the window on button click. If you want to decide if the button press really should close the window, you cant.

As someone commented, the code I have posted is not MVVM friendly, how about the second solution?

1st, not MVVM solution (I will not delete this as a reference)

2nd, probably better solution: Using attached behaviours

Ключевым элементом в системе графического интерфейса в WPF является окно, которое содержит все необходимые элементы управления. Окно в WPF представлено классом Window , который является производным от класса ContentControl. Поэтому окно является элементом управления содержимым, и как, к примеру, кнопка, может содержать в себе один дочерний элемент. Как правило, в его качестве выступает один из элементов компоновки, например, Grid.

Класс Window привносит ряд свойств, которые позволяют настроить окно приложения:

AllowsTransparency : при значении true позволяет установить прозрачный фон окна

Icon : представляет иконку, которая отображается в левом верхнем углу окна и в панели задач. Если иконка не установлена, то система будет использовать стандартную иконку по умолчанию.

Top : устанавливает отступ окна приложения от верхней границы экрана

Left : устанавливает отступ окна приложения от левой границы экрана

ResizeMode : задает режим изменения размеров окна. Может принимать следующие значения:

CanMinimize : окно можно только свернуть

NoResize : у окна нельзя изменить начальные размеры

CanResize : у окна можно изменять размеры

CanResizeWithGrip : в правом нижнем углу окна появляется визуализация того, что у окна можно изменять размеры

RestoreBounds : возвращает границы окна

ShowInTaskbar : при значении true иконка окна отображается на панели задач

SizeToContent : позволяет автоматически масштабировать размеры окна в зависимости от содержимого. Может принимать следующие значения:

Width : автоматически масштабируется только ширина

Height : автоматически масштабируется только высота

WidthAndHeight : автоматически масштабируются высота и ширина

Manual : автоматическое масштабирование отсутствует

Title : заголовок окна

Topmost : при значении true окно устанавливается поверх других окон приложения

WindowStartupLocation : устанавливает стартовую позицию окна. Может принимать следующие значения:

CenterOwner : если данное окно было запущено другим окном, то данное окно позиционируется относительно центра запустившего его окна

CenterScreen : окно помещается в центре экрана

Manual : позиция устанавливается вручную с помощью свойств Top и Left

WindowState : состояние окна. Возможные значения:

Maximized : раскрыто на весь экран

Normal : стандартное состояние

Жизненный цикл

В процессе работы окно в WPF проходит ряд этапов жизненного цикла, которые доступны нам через обработку событий класса Window:

Initialized : это событие возникает при инициализации окна, когда у него устанавливаются все свойства, но до применения к нему стилей и привязки данных. Это общее событие для всех элементов управления в WPF, поэтому следует учитывать, что сначала возникают события вложенных элементов, а затем их контейнеров. То есть событие Initialized окна приложения генерируется только после того, как отработает событие Initialized для всех вложенных элементов.

Loaded : возникает после полной инициализации окна и применения к нему стилей и привязки данных. После генерации этого события происходит визуализация элемента, и окно отображается на экране и становится видимым для пользователя

Closing : возникает при закрытии окна

Closed : возникает, когда окно становится закрытым

Unloaded : возникает после закрытия окна при выгрузке всех связанных ресурсов из памяти

Соответственно, если нам надо выполнить некоторые действия при загрузке или при закрытии окна, мы можем обработать события Loaded и Closing/Closed. Например, запишем в текстовый лог события жизненного цикла:

Читайте также: