¿Cómo elimino minimizar y maximizar de una ventana de tamaño variable en WPF?

80

WPF no proporciona la capacidad de tener una ventana que permita cambiar el tamaño, pero no tiene botones para maximizar o minimizar. Me gustaría poder hacer una ventana así para poder tener cuadros de diálogo de tamaño variable.

Soy consciente de que la solución significará usar pinvoke, pero no estoy seguro de qué llamar y cómo. Una búsqueda en pinvoke.net no mostró nada que me llamara la atención como lo que necesitaba, principalmente estoy seguro porque Windows Forms proporciona las propiedades CanMinimizey CanMaximizeen sus ventanas.

¿Alguien podría indicarme o proporcionarme un código (se prefiere C #) sobre cómo hacer esto?

Nidonocu
fuente

Respuestas:

113

He robado un código que encontré en los foros de MSDN e hice un método de extensión en la clase Window, como este:

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

La única otra cosa a recordar es que por alguna razón esto no funciona desde el constructor de una ventana. Lo solucioné arrojando esto en el constructor:

this.SourceInitialized += (x, y) =>
{
    this.HideMinimizeAndMaximizeButtons();
};

¡Espero que esto ayude!

Matt Hamilton
fuente
3
Un código algo más bonito en la ventana: protected override void OnSourceInitialized (EventArgs e) {base.OnSourceInitialized (e); this.HideMinimizeAndMaximizeButtons (); }
Dmitry Shechtman
1
¿Por qué no hacerlo aún más simple y suscribirse al evento SourceInitialized directamente en el método HideMinimizeAndMaximizeButtons ()? Entonces puede llamar al método desde el constructor y no tener que hacer nada más.
jmatthias
1
esta solución no cubre el doble clic en la barra de título.
Lonli-Lokli
1
¡Nota de resurrección! El método debe colocarse en el evento Windows Loaded porque el identificador no está definido en el evento Initialized.
SezMe
4
Después de todo este tiempo sabiendo que esta funcionalidad está presente en formularios de Windows, simplemente no entiendo que microsoft no haya puesto este tipo de funcionalidad en WPF desde el principio. Francamente, un diálogo con un cuadro de minimización y un libro de maximización parece poco profesional, y el doble clic en la barra de subtítulos es el mismo problema. Lamento ventilar un poco mi frustración por WPF, es muy bueno y tiene activos de cadena, pero de vez en cuando te encuentras con algo que debería ser simple y que finalmente no lo es.
Philip Stuyck
91

Una forma es configurar su ResizeMode="NoResize". Se comportará así. ingrese la descripción de la imagen aquí

¡Espero que esto ayude!

Musikero31
fuente
32
Esto haría que la ventana no cambiara de tamaño, lo que es directamente contrario a la pregunta.
Mashmagar
5
Generalmente, los usuarios de Google que buscan una forma de deshabilitar los botones de minimizar y maximizar no tienen un requisito específico para que la ventana sea redimensionable. Actualmente, este es el resultado superior para la consulta "wpf window disable minimizar" y esta respuesta responde correctamente a la pregunta. Independientemente, es una pena que MS no haya convertido la barra de título o toda la ventana en cromo como "solo otro control o propiedad". Demasiado legado del '90 ...
Emperador Orionii
2
En este caso, los elementos con ancho dinámico (por ejemplo, DockPanel) aún pueden cambiar el tamaño de la ventana. Pero ya no el usuario. Entonces, esta opción realmente cumplió con mis requisitos.
OneWorld
3
No responde a las preguntas, pero me ayudó. Gracias.
dkantowitz
@EmperorOrionii, aunque en ese momento esta página podría haber sido el mejor resultado de Google, de ninguna manera implica que esta respuesta sea la mejor cuando consideras que no aborda "¿Cómo elimino minimizar y maximizar de a resizable windowen WPF?" cuando elimina el aspecto "redimensionable" del producto terminado. Eso es como ayudar a alguien que quiere pintar su auto de rojo y en el proceso le quitas el motor.
MickyD
22

No sé si esto funciona para su req. visualmente ... Esto es

<Window x:Class="DataBinding.MyWindow" ...Title="MyWindow" Height="300" Width="300" 
    WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip">
Gishu
fuente
3
Esto casi funciona, pero aún es posible maximizar o minimizar la ventana si hace doble clic en la barra de título, hace clic derecho y usa el menú de control o el botón de la barra de tareas si está disponible. Además, por supuesto, parece una ventana de herramientas, no una ventana normal.
Nidonocu
Bien ... pero de nuevo en mi humilde opinión, la restricción parece extraña de que el usuario no puede maximizar, pero puede arrastrar y ampliar manualmente la ventana cambiando el tamaño. Pero es tu ventana ... tus reglas :)
Gishu
esto puede ser útil para situaciones en las que se ha configurado la ventana MaxWidthy / o MaxHeightla ventana.
Brett Ryan
6

Si alguien usa la ventana Devexpress (DXWindow), la respuesta aceptada no funciona. Un enfoque desagradable es

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;
    } 
}
Eldar
fuente
Probablemente leí cinco publicaciones diferentes antes de notar tu respuesta aquí. Esto funciona, pero qué asco. ¿Alguna vez encontraste una manera mejor?
DonBoitnott
3

Aquí hay una solución que estoy usando. Tenga en cuenta que el botón de maximizar todavía se muestra.

Margen:

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

Código detrás:

// Disable maximizing this window
private void Window_StateChanged(object sender, EventArgs e)
{
    if (this.WindowState == WindowState.Maximized)
        this.WindowState = WindowState.Normal;
}
Andrej
fuente
1
Preguntó cómo ocultar los botones pero mantener la funcionalidad.
Alexandru Dicu
Por mínimo que sea, la ventana parpadea. No tan agradable.
Mugen
2

Puede configurar ResizeMode = "NoResize" de la ventana si desea eliminar el botón Minimizar y Maximizar

Chinmay Behera
fuente
Ehh, pero luego no puede cambiar el tamaño, debería poder hacerlo
Karsten
0

Esta variante de la solución propuesta por @MattHamilton puede (y debe) ser llamada en el constructor de la Ventana. El truco consiste en suscribir a un delegado al SourceInitializedevento dentro del método de extensión.

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);
    };
}
Olivier Jacot-Descombes
fuente