Fenster-Zustandsänderung minimiert/maximiert erkennen bzw. den vorherigen Zustand merken

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Marcus Gräfe.

    Fenster-Zustandsänderung minimiert/maximiert erkennen bzw. den vorherigen Zustand merken

    Ich speichere von meinem Programm die zuletzt verwendete Fenstergröße (Breite/Höhe) und den Fensterzustand (normal/maximiert). Das ist grundsätzlich kein Problem.

    Nun möchte ich allerdings nicht den Minimiert-Zustand speichern. Denn öffnet der User das Programm erneut und es ist minimiert, könnte das zur Verwirrung führen. Ich möchte daher in dem Fall den Zustand abspeichern, den das Fenster vor der Minimierung hatte. Bei der Größe möchte ich ebenfalls die alte Größe speichern, wenn das Fenster maximiert wurde. Denn sonst ändert sich nach dem Laden der Einstellungen die Größe zwischen maximiert und normal nicht. Die Fensterposition soll ebenfalls vor dem Maximieren gemerkt werden.

    Nun dachte ich, ich könnte einfach ResizeBegin und ResizeEnd dafür verwenden. Die lösen aber nicht aus, wenn der Fensterzustand sich verändert, sondern nur bei Fensterbewegung und Veränderung der Größe mittels Fensterrand. Was kann ich tun?

    Zwar gibt es noch SizeChanged, Layout und Resize, aber wie merke ich mir den alten/vorherigen Zustand?

    Mein derzeitiger Code:

    VB.NET-Quellcode

    1. Private Sub FrmMainCfg_ResizeBegin(sender As Object, e As EventArgs) Handles Me.ResizeBegin
    2. ' -------------------------------------------
    3. ' Vor einer Fensterveränderung
    4. ' -------------------------------------------
    5. LastWinState = Me.WindowState ' Aktuellen Fensterzustand speichern
    6. ' Aktuelle Fenstergröße speichern
    7. LastWidth = Me.Width
    8. LastHeight = Me.Height
    9. ' Aktuelle Fensterposition speichern
    10. LastXPos = Me.Left
    11. LastYPos = Me.Top
    12. End Sub
    13. Private Sub FrmMainCfg_ResizeEnd(sender As Object, e As EventArgs) Handles Me.ResizeEnd
    14. ' -------------------------------------------
    15. ' Nach einer Fensterveränderung
    16. ' -------------------------------------------
    17. If Me.WindowState <> FormWindowState.Minimized Then
    18. LastWinState = Me.WindowState ' Fensterzustand speichern, wenn nicht minimiert
    19. ' Fenstergröße und -position speichern, wenn nicht maximiert (und nicht minimiert)
    20. If Me.WindowState <> FormWindowState.Maximized Then
    21. LastWidth = Me.Width
    22. LastHeight = Me.Height
    23. LastXPos = Me.Left
    24. LastYPos = Me.Top
    25. End If
    26. End If
    27. End Sub

    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    @Marcus Gräfe Ist das Fenster "normal", nimmst Du .Bounds.
    Ansonsten nimmst Du .RestoreBounds.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke, das ist ja fast zu einfach. ;)

    Allerdings ergibt sich noch das Problem, dass ich nicht den letzten WindowState vor dem Minimieren habe. Hast du da eine Idee? Also wenn das Fenster minimiert ist, wie war es vorher?

    EDIT: Hat sich erledigt!

    VB.NET-Quellcode

    1. Private Sub FrmMainCfg_Resize(sender As Object, e As EventArgs) Handles Me.Resize
    2. If Me.WindowState <> FormWindowState.Minimized Then
    3. LastWinState = Me.WindowState ' Fensterzustand speichern, wenn nicht minimiert
    4. End If
    5. End Sub

    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    @Marcus Gräfe Ja, das sieht blöd aus. Das Resize-Event sagt immer, welchen Zustand es annimmt, nicht aber, welcher zuvor da war.
    Ich hab da immer .Normal eingesetzt, das ist am einfachsten.
    Du müsstest eine Queue mit den letzten beiden Zuständen füttern, dann wäre Dein gesuchter Zustand der vorletzte.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Siehe mein EDIT. Ich speichere den aktuellen WindowState (wie zuvor auch schon) bei Programmstart und danach, wie gepostet, im Resize-Event. Das scheint zu funktionieren.

    Ich habe allerdings gerade in dem Zusammenhang ein anderes Problem. Weise ich nicht mehr Left und Top zu, um die Fensterposition festzulegen (wie zu VB6-Zeiten)? Me.Left = 615 ergibt in meinem aktuellen Fall einen Left-Wert von -8 (die Werte spielen vmtl. keine Rolle, Left nimmt einfach nichts an). Me.Bounds.Left (oder X) darf wohl nicht beschrieben werden.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    @Marcus Gräfe Aus dem Rectangle .Bounds kannst Du .Location und .Size rausholen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Rausholen ja, aber ich möchte den Wert gerne festlegen. Ich erhalte das hier: Der Ausdruck ist ein Wert und kann nicht als Ziel einer Zuweisung verwendet werden.

    EDIT: Hat sich nun auch erledigt! Ich muss natürlich beim Wiederherstellen die Position vor dem WindowState setzen! (Left und Top klappen also)
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Marcus Gräfe schrieb:

    Left und Top
    nicht, sondern .Location.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Marcus Gräfe Nichts.
    Wenn Du das Rectangle von .Bounds abspeicherst und als Rectangle zurückholst, ist mit .Location und .Size das Fenster in zwei Zeilen restauriert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @ErfinderDesRades Klar. @Marcus Gräfe hat mich da mit seinem VB6-Zeugs wuschig gemacht.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke, ich werde mir das für die Zukunft merken.

    In meinem aktuellen Fall muss ich aber jeden einzelnen Wert (also X, Y, Breite und Höhe) evtl. noch korrigieren, falls der User das Fenster zu groß gemacht oder aus dem Bildschirmbereich geschoben hat. Insofern ist es sowieso weitaus mehr als ein Einzeiler und ich arbeite daher hier ganz klassisch mit Width, Height, Top und Left.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum