How to remove minimize and maximize buttons from a resizable window?
Asked Answered
E

10

97

WPF doesn't provide the ability to have a window that allows resize but doesn't have maximize or minimize buttons. I'd like to able to make such a window so I can have resizable dialog boxes.

I'm aware the solution will mean using pinvoke but I'm not sure what to call and how. A search of pinvoke.net didn't turn up any thing that jumped out at me as what I needed, mainly I'm sure because Windows Forms does provide the CanMinimize and CanMaximize properties on its windows.

Could someone point me towards or provide code (C# preferred) on how to do this?

Extrabold answered 4/12, 2008 at 4:51 Comment(0)
S
128

I've stolen some code I found on the MSDN forums and made an extension method on the Window class, like this:

internal static class WindowExtensions
{
    // from winuser.h
    private const int GWL_STYLE      = -16,
                      WS_MAXIMIZEBOX = 0x10000,
                      WS_MINIMIZEBOX = 0x20000;

    [DllImport("user32.dll")]
    extern private static int GetWindowLong(IntPtr hwnd, int index);

    [DllImport("user32.dll")]
    extern private static int SetWindowLong(IntPtr hwnd, int index, int value);

    internal static void HideMinimizeAndMaximizeButtons(this Window window)
    {
        IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
        var currentStyle = GetWindowLong(hwnd, GWL_STYLE);

        SetWindowLong(hwnd, GWL_STYLE, (currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX));
    }
}

The only other thing to remember is that for some reason this doesn't work from a window's constructor. I got around that by chucking this into the constructor:

this.SourceInitialized += (x, y) =>
{
    this.HideMinimizeAndMaximizeButtons();
};
Sierra answered 4/12, 2008 at 5:0 Comment(9)
Perhaps it would make more sense to do this after the handle has been created, perhaps in a handler for the Initialized event on the Window?Dabber
A somewhat prettier code in the Window: protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); this.HideMinimizeAndMaximizeButtons(); }Giselagiselbert
Why not make it even simpler and and subscribe to the SourceInitialized event right in the HideMinimizeAndMaximizeButtons() method? Then you can call the method from the constructor and not have to anything else.Educable
The value variable should be of type int (Int32), not long (Int64). Then you don't need to cast it back to int in the next line.Coarse
this solution does not cover double-click on title-bar.Ginni
@Ginni Actually, it does. When the buttons are hidden using the Win32 API, it also disables the window context menu options and double-clicking the caption.Unbelievable
Resurrection Note! The method has to be put into the Windows Loaded event because the handle is not defined in the Initialized event.Communicable
After all this time knowing that this functionality is present in windows forms, I just don't understand that microsoft did not put this kind of functionality in WPF right from the start. Quite frankly, a dialog with a minimize box and a maximize book looks unprofessional, and the double clicking of the caption bar is just the same issue. Sorry ventilating my frustration over WPF a bit, it is very good and has string assets but once and a while you stumble on something that should be simple which eventually is not.Stud
The reason this doesn't work from the constructor is the window handle doesn't actually exist yet. Therefore, if you want to put this in the constructor without worrying about events or state or anything else, just call EnsureHandle on a WindowInteropHelper class and it will be created. Then you can use your call to hide the items. You can actually put all this code in a XAML behavior so you can set it in the XAML for the window directly, which I'd argue is where it makes the most sense.Leekgreen
A
116

One way is to set your ResizeMode="NoResize". It will behave like this. enter image description here

Ardenia answered 6/10, 2011 at 1:44 Comment(5)
This would make the window not resizable, which is directly contrary to the question.Educt
Generally googlers that look for a way to disable minimize and maximize buttons don't have specific requirement for having window to be resizable. Currently this is top result for "wpf window disable minimize" query and this answer correctly answers the question. Regardless, shame that MS didn't made title bar or whole window chrome as "just another control or property". Too much legacy from '90...Tungusic
In this case elements with dynamic width (e.g. DockPanel) are still able to change the window size. But not the user anymore. So, this option actually met my requirements.Languorous
Doesn't answer the questions, but was helpful to me. Thanks.Margalit
@EmperorOrionii whilst at the time this page might have been the top Google result, in no way does it imply this answer is the best when you consider it does not address "How do I remove minimize and maximize from a resizable window in WPF?" when it removes the "resizable" aspect from the finished product. That's like helping someone who wants to paint their car red and in the process you remove the engine.Hirudin
M
28

Don't know if this works for your req. visually.. This is

<Window x:Class="DataBinding.MyWindow" ...Title="MyWindow" Height="300" Width="300" 
    WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip">
Magdalen answered 4/12, 2008 at 5:33 Comment(3)
This almost works, but its still possible to maximize or minimize the window if you double click the title bar, right click and use the control menu or the taskbar button if it is avalible. Plus of course it looks like a tool window, not a normal one.Extrabold
Right... but then again IMHO the constraint seems odd that the user is not allowed to maximise but can manually drag-enlarge the window by resizing. But it's your window.. your rules :)Magdalen
this can be handy for situations where the MaxWidth and/or MaxHeight of the window has been set.Illogic
T
6

If anyone use Devexpress window (DXWindow) accepted answer doesn't work. One ugly approach is

public partial class MyAwesomeWindow : DXWindow
{
    public MyAwesomeWIndow()
    {
       Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        // hides maximize button            
        Button button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_Maximize.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;

        // hides minimize button
        button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_Minimize.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;

        // hides close button
        button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_CloseButton.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;
    } 
}
Telephoto answered 28/3, 2013 at 9:52 Comment(1)
I probably read five different posts before I noticed your answer down here. This does work, but yuck. Did you ever find a better way?Onega
U
4

Here's a solution I'm using. Note that maximize button is still displayed.

Markup:

<Window x:Class="Example"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Example"
        StateChanged="Window_StateChanged">

Code behind:

// Disable maximizing this window
private void Window_StateChanged(object sender, EventArgs e)
{
    if (this.WindowState == WindowState.Maximized)
        this.WindowState = WindowState.Normal;
}
Une answered 10/5, 2011 at 19:33 Comment(2)
He asked how to hide the buttons but keep the functionality.Frond
As minimal as this is, the window is flickering. Not so nice.Paravane
C
3

This variant of the solution proposed by @MattHamilton can (and must) be called in the constructor of the Window. The trick is to subscribe a delegate to the SourceInitialized event within the extension method.

private const int GWL_STYLE = -16, WS_MAXIMIZEBOX = 0x10000, WS_MINIMIZEBOX = 0x20000;

[DllImport("user32.dll")]
extern private static int GetWindowLong(IntPtr hwnd, int index);

[DllImport("user32.dll")]
extern private static int SetWindowLong(IntPtr hwnd, int index, int value);

/// <summary>
/// Hides the Minimize and Maximize buttons in a Window. Must be called in the constructor.
/// </summary>
/// <param name="window">The Window whose Minimize/Maximize buttons will be hidden.</param>
public static void HideMinimizeAndMaximizeButtons(this Window window)
{
    window.SourceInitialized += (s, e) => {
        IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
        int currentStyle = GetWindowLong(hwnd, GWL_STYLE);

        SetWindowLong(hwnd, GWL_STYLE, currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
    };
}
Chauvinism answered 18/10, 2018 at 13:5 Comment(0)
S
2

You can set the ResizeMode="NoResize" of the window if you want to remove Minimize and Maximize button

Satin answered 15/9, 2010 at 4:38 Comment(1)
Ehh but then you can't resize it should be able toInalterable
D
2

Just use

WindowStyle="ToolWindow"

It hides the maximize and minimize buttons, but the window can still be resized by dragging the window borders and minimize using the hide button in the bottom right corner of the taskbar.

https://learn.microsoft.com/en-us/dotnet/api/system.windows.window.windowstyle?view=windowsdesktop-6.0

Drumm answered 5/7, 2022 at 6:54 Comment(0)
M
0

You can add ResizeMode="CanMinimize" to

<Window x:Class="ModernDesign.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

It doesn't outright remove the maximize button (it only grays it out) but the functionality of the minimize and close buttons still remain.

(I'm sorry if this answer is confusing, I'm still very new to .xaml)

Mulkey answered 30/10, 2023 at 21:36 Comment(0)
T
0

I was recently working on a WPF app and needed to do this. While I like the answers provided on here, some of the answers are bit of an overkill to just hide two buttons. I experimented with @StefanSander's answer and found it to be the simplest to implement out of the box. However, this changes the resulting window slightly, causing the Close button to be rather ugly IMO.

What I did instead was to set the WindowStyle property to SingleBorderWindow which removed the two buttons leaving just the Close button.

WindowStyle="SingleBorderWindow"

Since I didn't want the window resized, I added the below:

ResizeMode="NoResize"
Tourism answered 1/4, 2024 at 19:39 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.