Wie entferne ich Minimieren und Maximieren aus einem Fenster mit veränderbarer Größe in WPF?

79

WPF bietet keine Möglichkeit, ein Fenster zu erstellen, in dem die Größe geändert werden kann, jedoch keine Schaltflächen zum Maximieren oder Minimieren. Ich möchte ein solches Fenster erstellen können, damit ich die Größe der Dialogfelder ändern kann.

Ich bin mir bewusst, dass die Lösung die Verwendung von Pinvoke bedeuten wird, bin mir aber nicht sicher, wie und wie ich anrufen soll. Eine Suche in pinvoke.net ergab nichts, was mir als das heraussprang, was ich brauchte. Ich bin mir hauptsächlich sicher, dass Windows Forms die Eigenschaften CanMinimizeund CanMaximizein seinen Fenstern bereitstellt .

Könnte mich jemand darauf hinweisen oder Code (C # bevorzugt) angeben, wie das geht?

Nidonocu
quelle

Antworten:

111

Ich habe Code gestohlen, den ich in den MSDN-Foren gefunden habe, und eine Erweiterungsmethode für die Window-Klasse erstellt, wie folgt:

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

Die einzige andere Sache, an die Sie sich erinnern sollten, ist, dass dies aus irgendeinem Grund vom Konstruktor eines Fensters aus nicht funktioniert. Ich habe das umgangen, indem ich das in den Konstruktor geworfen habe:

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

Hoffe das hilft!

Matt Hamilton
quelle
3
Ein etwas hübscherer Code im Fenster: protected override void OnSourceInitialized (EventArgs e) {base.OnSourceInitialized (e); this.HideMinimizeAndMaximizeButtons (); }
Dmitry Shechtman
1
Warum nicht noch einfacher machen und das SourceInitialized-Ereignis direkt in der HideMinimizeAndMaximizeButtons () -Methode abonnieren? Dann können Sie die Methode vom Konstruktor aus aufrufen und müssen nichts anderes.
Jmatthias
1
Diese Lösung deckt keinen Doppelklick auf die Titelleiste ab.
Lonli-Lokli
1
Auferstehungsnotiz! Die Methode muss in das Windows Loaded-Ereignis eingefügt werden, da das Handle im Initialized-Ereignis nicht definiert ist.
SezMe
4
Nach all der Zeit, in der ich wusste, dass diese Funktionalität in Windows Forms vorhanden ist, verstehe ich einfach nicht, dass Microsoft diese Funktionalität nicht von Anfang an in WPF integriert hat. Ehrlich gesagt sieht ein Dialog mit einem Minimierungsfeld und einem Maximierungsbuch unprofessionell aus, und das Doppelklicken auf die Beschriftungsleiste ist genau das gleiche Problem. Es tut mir leid, dass ich meine Frustration über WPF ein wenig lüfte, es ist sehr gut und hat String-Assets, aber hin und wieder stolpert man über etwas, das einfach sein sollte, was letztendlich nicht der Fall ist.
Philip Stuyck
89

Eine Möglichkeit besteht darin, Ihre Einstellungen vorzunehmen ResizeMode="NoResize". Es wird sich so verhalten. Geben Sie hier die Bildbeschreibung ein

Ich hoffe das hilft!

Musikero31
quelle
31
Dies würde dazu führen, dass die Größe des Fensters nicht geändert werden kann, was der Frage direkt widerspricht.
Mashmagar
5
Im Allgemeinen müssen Googler, die nach einer Möglichkeit suchen, die Minimierungs- und Maximierungsschaltflächen zu deaktivieren, keine besonderen Anforderungen an die Größe des Fensters stellen. Derzeit ist dies das beste Ergebnis für die Abfrage "wpf window disable minimieren", und diese Antwort beantwortet die Frage korrekt. Schade, dass MS die Titelleiste oder das gesamte Fenster nicht als "nur ein weiteres Steuerelement oder eine andere Eigenschaft" verchromt hat. Zu viel Vermächtnis von '90 ...
Kaiser Orionii
2
In diesem Fall können Elemente mit dynamischer Breite (z. B. DockPanel) die Fenstergröße weiterhin ändern. Aber nicht mehr der Benutzer. Diese Option entsprach also tatsächlich meinen Anforderungen.
OneWorld
3
Beantwortet die Fragen nicht, war aber hilfreich für mich. Vielen Dank.
Dkantowitz
22

Ich weiß nicht, ob dies für Ihre Anforderung funktioniert. visuell .. Dies ist

<Window x:Class="DataBinding.MyWindow" ...Title="MyWindow" Height="300" Width="300" 
    WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip">
Gishu
quelle
3
Dies funktioniert fast, aber es ist immer noch möglich, das Fenster zu maximieren oder zu minimieren, wenn Sie auf die Titelleiste doppelklicken, mit der rechten Maustaste klicken und das Steuerungsmenü oder die Taskleistenschaltfläche verwenden, wenn es verfügbar ist. Außerdem sieht es natürlich wie ein Werkzeugfenster aus, nicht wie ein normales.
Nidonocu
Richtig ... aber meiner Meinung nach scheint die Einschränkung seltsam, dass der Benutzer nicht maximieren darf, sondern das Fenster durch Größenänderung manuell ziehen und vergrößern kann. Aber es ist dein Fenster ... deine Regeln :)
Gishu
Dies kann praktisch sein, wenn das MaxWidthund / oder MaxHeightdas Fenster eingestellt wurde.
Brett Ryan
6

Wenn jemand das Devexpress-Fenster (DXWindow) verwendet, funktioniert die akzeptierte Antwort nicht. Ein hässlicher Ansatz ist

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
quelle
Ich habe wahrscheinlich fünf verschiedene Beiträge gelesen, bevor ich Ihre Antwort hier unten bemerkt habe. Das funktioniert, aber igitt. Hast du jemals einen besseren Weg gefunden?
DonBoitnott
3

Hier ist eine Lösung, die ich verwende. Beachten Sie, dass die Schaltfläche zum Maximieren weiterhin angezeigt wird.

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 dahinter:

// Disable maximizing this window
private void Window_StateChanged(object sender, EventArgs e)
{
    if (this.WindowState == WindowState.Maximized)
        this.WindowState = WindowState.Normal;
}
Andrej
quelle
1
Er fragte, wie man die Tasten versteckt, aber die Funktionalität beibehält.
Alexandru Dicu
So minimal dies auch ist, das Fenster flackert. Nicht so schön.
Mugen
2

Sie können den ResizeMode = "NoResize" des Fensters festlegen, wenn Sie die Schaltfläche "Minimieren" und "Maximieren" entfernen möchten

Chinmay Behera
quelle
Ehh aber dann kann man die Größe nicht ändern, es sollte möglich sein
Karsten
0

Diese von @MattHamilton vorgeschlagene Variante der Lösung kann (und muss) im Konstruktor des Fensters aufgerufen werden. Der Trick besteht darin, einen Delegaten für das SourceInitializedEreignis innerhalb der Erweiterungsmethode zu abonnieren .

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
quelle