Jak usunąć minimalizowanie i maksymalizowanie z okna o zmiennym rozmiarze w WPF?

80

WPF nie zapewnia możliwości posiadania okna, które umożliwia zmianę rozmiaru, ale nie ma przycisków maksymalizacji ani minimalizacji. Chciałbym móc zrobić takie okno, aby móc zmieniać rozmiar okien dialogowych.

Wiem, że rozwiązanie będzie oznaczało użycie pinvoke, ale nie jestem pewien, do czego i jak zadzwonić. Wyszukiwanie pinvoke.net nie przyniosło niczego, co wyskoczyło na mnie jako to, czego potrzebowałem, głównie jestem pewien, ponieważ Windows Forms zapewnia właściwości CanMinimizei CanMaximizew swoich oknach.

Czy ktoś może wskazać mi lub podać kod (preferowany w C #), jak to zrobić?

Nidonocu
źródło

Odpowiedzi:

114

Ukradłem kod, który znalazłem na forach MSDN i utworzyłem metodę rozszerzenia dla klasy Window, na przykład:

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

Jedyną inną rzeczą do zapamiętania jest to, że z jakiegoś powodu to nie działa z konstruktora okna. Obejrzałem to, wrzucając to do konstruktora:

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

Mam nadzieję że to pomoże!

Matt Hamilton
źródło
3
Nieco ładniejszy kod w Window: protected override void OnSourceInitialized (EventArgs e) {base.OnSourceInitialized (e); this.HideMinimizeAndMaximizeButtons (); }
Dmitry Shechtman
1
Dlaczego nie uczynić tego jeszcze prostszym i nie zasubskrybować zdarzenia SourceInitialized bezpośrednio w metodzie HideMinimizeAndMaximizeButtons ()? Następnie możesz wywołać metodę z konstruktora i nie musisz nic więcej.
jmatthias,
1
to rozwiązanie nie obejmuje dwukrotnego kliknięcia paska tytułowego.
Lonli-Lokli
1
Uwaga o zmartwychwstaniu! Metodę należy umieścić w zdarzeniu Windows Loaded, ponieważ uchwyt nie jest zdefiniowany w zdarzeniu Initialized.
SezMe
4
Po całym tym czasie, wiedząc, że ta funkcjonalność jest obecna w formularzach Windows, po prostu nie rozumiem, że Microsoft nie umieścił tego rodzaju funkcjonalności w WPF od samego początku. Szczerze mówiąc, okno dialogowe z polem minimalizacji i książką maksymalizacji wygląda nieprofesjonalnie, a dwukrotne kliknięcie paska tytułu to ten sam problem. Przepraszam, wentylując trochę moją frustrację związaną z WPF, jest bardzo dobry i ma aktywa ciągowe, ale raz na jakiś czas natkniesz się na coś, co powinno być proste, a ostatecznie nie jest.
Philip Stuyck
92

Jednym ze sposobów jest ustawienie ResizeMode="NoResize". Będzie się tak zachowywać. wprowadź opis obrazu tutaj

Mam nadzieję, że to pomoże!

Musikero31
źródło
33
To spowodowałoby, że nie można zmienić rozmiaru okna, co jest bezpośrednio sprzeczne z pytaniem.
Mashmagar
5
Zwykle pracownicy Google, którzy szukają sposobu na wyłączenie przycisków minimalizacji i maksymalizacji, nie mają specjalnych wymagań dotyczących zmiany rozmiaru okna. Obecnie jest to najwyższy wynik dla zapytania "wpf okno wyłącz minimalizuj" i ta odpowiedź poprawnie odpowiada na pytanie. Niezależnie od tego, szkoda, że ​​MS nie stworzył paska tytułu lub całego okna jako „tylko kolejnej kontrolki lub właściwości”. Za dużo spuścizny z '90 ...
Cesarz Orionii
2
W tym przypadku elementy z dynamiczną szerokością (np. DockPanel) nadal mogą zmieniać rozmiar okna. Ale już nie użytkownik. Tak więc ta opcja faktycznie spełniła moje wymagania.
OneWorld
4
Nie odpowiada na pytania, ale był dla mnie pomocny. Dzięki.
dkantowitz
@EmperorOrionii Chociaż w tamtym czasie ta strona mogła być najlepszym wynikiem w Google, w żaden sposób nie oznacza to, że ta odpowiedź jest najlepsza, jeśli uważasz, że nie dotyczy ona „Jak usunąć minimalizowanie i maksymalizowanie z elementu resizable windowWPF?” gdy usuwa się „resizable” Aspekt z gotowego produktu. To tak, jakby pomóc komuś, kto chce pomalować swój samochód na czerwono, a przy okazji zdjąć silnik.
MickyD
22

Nie wiem, czy to działa w przypadku Twojego wymagania. wizualnie .. to jest

<Window x:Class="DataBinding.MyWindow" ...Title="MyWindow" Height="300" Width="300" 
    WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip">
Gishu
źródło
3
To prawie działa, ale nadal można zmaksymalizować lub zminimalizować okno po dwukrotnym kliknięciu paska tytułu, kliknięciu prawym przyciskiem myszy i użyciu menu sterowania lub przycisku paska zadań, jeśli jest dostępny. Poza tym wygląda jak okno narzędziowe, a nie normalne.
Nidonocu
Racja ... ale z drugiej strony IMHO ograniczenie wydaje się dziwne, że użytkownik nie może maksymalizować, ale może ręcznie przeciągnąć i powiększyć okno, zmieniając rozmiar. Ale to twoje okno… twoje zasady :)
Gishu
może to być przydatne w sytuacjach, w których ustawiono MaxWidthi / lub MaxHeightokno.
Brett Ryan
6

Jeśli ktoś używa okna Devexpress (DXWindow) zaakceptowana odpowiedź nie działa. Jedno brzydkie podejście to

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
źródło
Prawdopodobnie przeczytałem pięć różnych postów, zanim zauważyłem tutaj twoją odpowiedź. To działa, ale fuj. Czy kiedykolwiek znalazłeś lepszy sposób?
DonBoitnott
3

Oto rozwiązanie, którego używam. Zwróć uwagę, że przycisk maksymalizacji jest nadal wyświetlany.

Narzut:

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

Kod za:

// Disable maximizing this window
private void Window_StateChanged(object sender, EventArgs e)
{
    if (this.WindowState == WindowState.Maximized)
        this.WindowState = WindowState.Normal;
}
Andrej
źródło
1
Zapytał, jak ukryć przyciski, ale zachować funkcjonalność.
Alexandru Dicu
Choć jest to minimalne, okno migocze. Niezbyt miły.
Mugen,
2

Możesz ustawić ResizeMode = "NoResize" okna, jeśli chcesz usunąć przycisk Minimalizuj i Maksymalizuj

Chinmay Behera
źródło
1
Ech, ale wtedy nie możesz zmienić rozmiaru, to powinno być w stanie
Karsten
0

Ten wariant rozwiązania zaproponowany przez @MattHamilton może (i musi) zostać wywołany w konstruktorze Window. Sztuczka polega na zasubskrybowaniu delegata do SourceInitializedzdarzenia w ramach metody rozszerzenia.

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
źródło