Creating a custom Close Button in WPF

48,160

Solution 1

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

Solution 2

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

Solution 3

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

Solution 4

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

Share:
48,160
kumarharsh
Author by

kumarharsh

I'm currently working at Google as a Software Engineer. Previously, I've worked as a UI Engineer at Flipkart (India's largest e-commerce platform) where I designed the front-end architecture for their vendor portal in GraphQL. Before that, I served as co-founder &amp; head of UI/UX at Playlyfe, I have created frontends for several products from scratch, lead the design team, and played a significant part in building backend infrastructure.

Updated on July 09, 2022

Comments

  • kumarharsh
    kumarharsh almost 2 years

    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.