Click here to Skip to main content
13,663,447 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

15.2K views
4 bookmarked
Posted 10 Nov 2016
Licenced Public Domain

How to Remove the Close Button from a WPF ToolWindow

, 10 Nov 2016
Rate this:
Please Sign up or sign in to vote.
This tip shows how to remove the close window from a WPF ToolWindow, so that exiting the window can be tightly controlled.

Introduction

One of the things I’ve had to do over the years is remove the Close box from a WPF window, in order to create a tools or response-type window that the user can only exit by selecting one of the buttons that I provide him. I use it so frequently that I eventually created my own class, inherited from the Window class, that contains the extra functionality.

NOTE: This solution is aimed at windows with the Style of ToolWindow… it simply removes the close button in the upper-right corner in order to control more tightly how exit from the window is accomplished.

Keep in mind also that this solution will work for any windows, not just those with a ToolWindow style, EXCEPT that it will also remove the minimize and maximize buttons.

Using the Code

This is a walkthrough of the process for creating a WPF ToolWindow, using a brand-new project as an example. Simply follow the steps outlined here to make it work.

The project I created was called SampleRemoveCloseBox, and that was also the name of the namespace.

First, create a new WPF project, and add a single button to close the program. The XAML should look like this:

//
// XAML Code, window with close button
//
<Window x:Class="SampleRemoveCloseBox.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="350" 

        Width="525" WindowStyle="ToolWindow">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Button Name="btnClose" Margin="5,5,5,5" 

        Click="btnClose_Click">Close the Program</Button>
    </Grid>
</Window>
...

And the program when run looks like this:

The goal is to remove the close box in the upper right corner, so that the only way to exit the program is by pressing the button.

In the code-behind, create the class for the window.

//
// C# Code, CustomWindow class declaration
//
public partial class CustomWindow : Window
{
    // Prep stuff needed to remove close button on window
    private const int GWL_STYLE = -16;
    private const int WS_SYSMENU = 0x80000;
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    public CustomWindow()
    {
        Loaded += ToolWindow_Loaded;
    }

    void ToolWindow_Loaded(object sender, RoutedEventArgs e)
    {
        // Code to remove close box from window
        var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
    }
}...

This is the code that removes the close button. If you want to do this without the custom class, just place the prep stuff in your window class, and then the actual code in the loaded event for your window.

But to continue this tutorial, change the window definition to inherit from this class instead of window.

//
// C# Code, inherit window from CustomWindow
//
public partial class MainWindow : CustomWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }
}
...

Now change the XAML to also inherit from that class instead of window.

//
// XAML Code, window is of CustomWindow class
//
<local:CustomWindow x:Class="SampleRemoveCloseBox.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:local="clr-namespace:SampleRemoveCloseBox"

        Title="MainWindow" Height="350" 

        Width="525" WindowStyle="ToolWindow">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Button Name="btnClose" Margin="5,5,5,5" 

        Click="btnClose_Click">Close the Program</Button>
    </Grid>
</local:CustomWindow>...

And now the program when run looks like this:

Notice that the close button is gone from the upper right corner of the program. This can be used for popup dialog boxes for which a response is required, or any kind of a data entry window where the user should use the provided methods to leave the window. Basically, it is useful anywhere you use a ToolWindow.

The title bar is not strictly under WPF control, so what you can do with it is limited. Because of that, you need to set the window style using WIN32 calls, but they work well enough.

And that's all there is to it. A pretty simple solution, even though it is incredibly NOT intuitively obvious.

Points of Interest

For a long time, I simply dropped the relevant code onto any form I needed it on, but eventually I did create a CustomWindow class that automatically included that functionality, making it even easier to implement this solution.

History

  • 2016-11-09 -- Original version

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

Matthew Givens
Software Developer (Senior)
United States United States
Matthew Givens has been a software developer since 1988, and has worked for numerous companies over the years. He currently works in the healthcare industry, developing with C# .NET and Sql-Server.

You may also be interested in...

Comments and Discussions

 
SuggestionAttached Behaviour Pin
Richard Deeming10-Nov-16 6:58
mvpRichard Deeming10-Nov-16 6:58 
GeneralRe: Attached Behaviour Pin
Bernhard Hiller10-Nov-16 22:24
professionalBernhard Hiller10-Nov-16 22:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01-2016 | 2.8.180810.1 | Last Updated 10 Nov 2016
Article Copyright 2016 by Matthew Givens
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid