I need to implement a custom window decorator where a Close button will behave exactly as the close or x button on all Windows applications.
6 Answers
Simply call the close()
function from your button:
WPF:
<Button Name="CloseButton" Content="x" Click="CloseButton_Click" />
code-behind:
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}

- 16,418
- 9
- 48
- 68
-
2I tried command="close" and nothing happens. Is there something else that needs to be done to get command="close" to actually close the window? – James Sep 11 '14 at 15:23
If you want the Button which will close the dialog Window
, you can add for him IsCancel
property:
<Button Name="CloseButton"
IsCancel="True" ... />
This means the following MSDN
:
When you set the
IsCancel
property of a Button to true, you create a Button that is registered with the AccessKeyManager. The button is then activated when a user presses the ESC key.
Now, if you click on this Button, or press Esc then dialog Window
is closing, but it does not work for the normal MainWindow
.
To close the MainWindow
, you can simply add a Click handler which has already been shown. But if you want a more elegant solution that would satisfy the MVVM style you can add the following attached behavior:
public static class ButtonBehavior
{
#region Private Section
private static Window MainWindow = Application.Current.MainWindow;
#endregion
#region IsCloseProperty
public static readonly DependencyProperty IsCloseProperty;
public static void SetIsClose(DependencyObject DepObject, bool value)
{
DepObject.SetValue(IsCloseProperty, value);
}
public static bool GetIsClose(DependencyObject DepObject)
{
return (bool)DepObject.GetValue(IsCloseProperty);
}
static ButtonBehavior()
{
IsCloseProperty = DependencyProperty.RegisterAttached("IsClose",
typeof(bool),
typeof(ButtonBehavior),
new UIPropertyMetadata(false, IsCloseTurn));
}
#endregion
private static void IsCloseTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool && ((bool)e.NewValue) == true)
{
if (MainWindow != null)
MainWindow.PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
var button = sender as Button;
if (button != null)
button.Click += new RoutedEventHandler(button_Click);
}
}
private static void button_Click(object sender, RoutedEventArgs e)
{
MainWindow.Close();
}
private static void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
MainWindow.Close();
}
}
And in Window
use like this:
<Window x:Class="MyProjectNamespace.MainWindow"
xmlns:local="clr-namespace:MyProjectNamespace">
<Button Name="CloseButton"
local:ButtonBehavior.IsClose="True" ... />
Now the MainWindow
can be closed by clicking on the Button or pressing Esc, and it all happens independent from View
(UI).

- 22,370
- 15
- 69
- 68
If you would like to use MVVM architecture, then you can pass the name of your window as a Command Parameter and in the Command you can close the window.
The code would be something like this:
Button Command="{Binding MainCloseButtonCommand}"
CommandParameter="{Binding ElementName=mainWindow}"
private void performMainCloseButtonCommand(object Parameter)
{
Window objWindow = Parameter as Window;
objWindow.Close();
}
If you add a button to your current view lets say from code behind:
var closeButton = new Button();
closeButton.Click += closeButton_Click;
// Add the button to the window
Content = closeButton;
Then you can respond to the event and just call Close()
like this:
void closeButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
What this basicly does is that it adds a button to your Window
/ UserControl
and when you press it, it will close the Window.
If you do it from XAML
it could look like this:
<Button Name="closeButton" Click="closeButton_Click" />

- 36,033
- 20
- 126
- 183
Actually it is this:
<Window Name = "Chrome">
.
.
<Button Name="closeButton" onClick="terminateApplication"/>
.
</Window>
and in the CS file,
private void terminateApplication(object sender, RoutedEventArgs e)
{
Chrome.Close();
}

- 18,961
- 8
- 72
- 100
-
What do I not understand about this? If you are within the code-behind of the window, you don't need to call it by name. So your code is basically a longer version of the code in the other answers. I'm afraid your answer is risking a downvote. – Martin Hennings Mar 04 '11 at 12:52
-
this was a more 'generalized' answer.... also, i was writing this when 2 more answers poured in... :D – kumarharsh Mar 04 '11 at 13:02
Use close button with viewmodel. View model IS NOT DEPEND on gui.
namespace YourLibrary.ComponentModel
{
/// <summary>
/// Defines Close method. Use for window, file stream,....
/// </summary>
public interface IClosable
{
/// <summary>
/// Close of instance (window, file stream,... etc).
/// </summary>
void Close();
}
}
MyWindow.xaml
<Window ...
x:Name="ThisInstance"
...
>
<Button Command="{Binding ButtonCommand}" CommandParameter="{Binding ElementName=ThisInstance}">
MyWindow.xaml.cs
public partial class MyWindow : Window, YourLibrary.ComponentModel.IClosable
{
....
}
MyViewModel.cs
public class MyViewModel
{
ICommand buttonCommand;
/// <summary>
/// Command for Button.
/// Default action is close the window.
/// Close window via retyping parameter as <see cref="IClosable"/>
/// </summary>
public ICommand ButtonCommand => buttonCommand ?? (buttonCommand=new RelayCommand(ButtonCommandExecute));
void ButtonCommandExecute (object obj)
{
var myWindow = (IClosable)obj;
myWindow.Close();
};
TESTING, USE VIEWMODEL IN CONSOLE
class Program
{
public class ConsoleWindow : YourLibrary.ComponentModel.IClosable
{
public void Close()
{
Console.WriteLine("Closing area...");
}
}
static void Main(string[] args)
{
var program = new Program();
program.DoMain(args);
}
public void DoMain(string[] args)
{
var consoleWindow = new ConsoleWindow();
var viewModel = new MyViewModel()
viewModel.ButtonCommand.Execute(consoleWindow);
}
}

- 189
- 1
- 6