54 Stimmen

.NET / Windows Forms: Fenstergröße und -position merken

Ich habe eine Windows Forms-Anwendung mit einem normalen Fenster. Wenn ich nun die Anwendung schließe und neu starte, möchte ich, dass das Hauptfenster an der gleichen Stelle auf meinem Bildschirm mit der gleichen Größe erscheint, wie zum Zeitpunkt des Schließens.

Gibt es in Windows Forms eine einfache Möglichkeit, sich die Position des Bildschirms und die Fenstergröße (und wenn möglich den Fensterstatus) zu merken, oder muss alles von Hand gemacht werden?

2 Stimmen

Diese Frage wurde schon einmal gestellt und hier beantwortet: (Es ist eine gute Antwort. Stellen Sie sicher, dass Sie @Joe ein Upvote geben, wenn Sie sie verwenden.) Es ist keine exakte Kopie - diese Person hat nicht nach der Fenstergröße gefragt, aber Sie sollten in der Lage sein, von dort zu extrapolieren. stackoverflow.com/questions/105932/

0 Stimmen

Habe meinen Kommentar zusammen mit Ihrem Beitrag gelöscht... doh. Ich bin anderer Meinung, da die Lösung einen UserPreferencesManager verwendet, der, soweit ich weiß, eine benutzerdefinierte Klasse ist. Ich glaube, die Frage ist, wie Sie eine solche UserPreferencesManager-Klasse implementieren würden.

1 Stimmen

Bitte beachten Sie, dass, wenn der Benutzer eine variable Bildschirmgröße hat (z.B. wenn er manchmal einen Monitor an die nb anschließt oder eine Remote-Verbindung mit unterschiedlicher Bildschirmgröße herstellt), dieser Versuch zu einem frustrierenden Zustand führen kann, wenn Ihre Anwendung außerhalb des Bildschirmrahmens erscheint. Prüfen Sie stackoverflow.com/questions/105932/ für komplexere Lösungen.

84voto

ChrisF Punkte 130622

Wenn Sie diesen Code in Ihre FormClosing Ereignisbehandler:

if (WindowState == FormWindowState.Maximized)
{
    Properties.Settings.Default.Location = RestoreBounds.Location;
    Properties.Settings.Default.Size = RestoreBounds.Size;
    Properties.Settings.Default.Maximised = true;
    Properties.Settings.Default.Minimised = false;
}
else if (WindowState == FormWindowState.Normal)
{
    Properties.Settings.Default.Location = Location;
    Properties.Settings.Default.Size = Size;
    Properties.Settings.Default.Maximised = false;
    Properties.Settings.Default.Minimised = false;
}
else
{
    Properties.Settings.Default.Location = RestoreBounds.Location;
    Properties.Settings.Default.Size = RestoreBounds.Size;
    Properties.Settings.Default.Maximised = false;
    Properties.Settings.Default.Minimised = true;
}
Properties.Settings.Default.Save();

Es wird der aktuelle Zustand gespeichert.

Fügen Sie dann den folgenden Code in Ihr Formular ein OnLoad Handler:

if (Properties.Settings.Default.Maximised)
{
    Location = Properties.Settings.Default.Location;
    WindowState = FormWindowState.Maximized;
    Size = Properties.Settings.Default.Size;
}
else if (Properties.Settings.Default.Minimised)
{
    Location = Properties.Settings.Default.Location;
    WindowState = FormWindowState.Minimized;
    Size = Properties.Settings.Default.Size;
}
else
{
    Location = Properties.Settings.Default.Location;
    Size = Properties.Settings.Default.Size;
}

Es wird der letzte Zustand wiederhergestellt.

Es merkt sich sogar, auf welchem Monitor in einer Mehrmonitor-Konfiguration die Anwendung maximiert wurde.

31 Stimmen

Für diejenigen unter Ihnen, die Properties.Settings noch nicht verwendet haben, müssen Sie in die Projekteigenschaften gehen und die Registerkarte Einstellungen aufrufen. Erstellen Sie eine Datei mit Standardeinstellungen und fügen Sie eine Eigenschaft namens Standort und eine namens Größe hinzu.

0 Stimmen

Der Code für die Speicherung Ihres Standorts schlägt fehl, wenn das Formular minimiert ist. Sie müssen auch auf FormWindowState.Minimized prüfen. Ist "Maximised" ein Tippfehler für "Maximized"?

0 Stimmen

@EricLaw - "Maximiert" ist der Name der Eigenschaft. Ich nehme an, es sollte "Maximiert" für die Konsistenz sein. Re Überprüfung für "Minimiert" - es war etwas, das ich nicht in der App, die ich nahm diese aus.

36voto

Walter Punkte 2492

Sie müssen die Position und Größe des Fensters in Ihren Anwendungseinstellungen speichern. Hier ist eine gute C# Artikel um Ihnen zu zeigen wie.

EDITAR

Sie können so ziemlich alles, was Sie wollen, in den Anwendungseinstellungen speichern. In der Spalte Typ des Einstellungsrasters können Sie einen beliebigen .NET-Typ auswählen. WindowState befindet sich in System.Windows.Forms und ist als FormWindowState aufgeführt. Es gibt auch eine Eigenschaft für FormStartPosition.

0 Stimmen

Danke, das ist ein guter Artikel. Das Einzige, was übrig bleibt, ist, sich den Fensterstatus zu merken (maximiert, minimiert, ...), wie kann ich das in die Einstellungen einfügen?

0 Stimmen

Ja, danke. Mir war zunächst nicht klar, dass man in diesen Einstellungen nach allen Arten von .NET suchen kann.

0 Stimmen

Danke! Eine Sache noch: Wenn das Fenster maximiert ist, wie kann ich mir merken, auf welchem Monitor es in einem Multi-Monitor-Setup maximiert ist?

8voto

jing Punkte 1807

Die bisherigen Lösungen haben bei mir nicht funktioniert. Nach dem Spielen eine Weile landete ich mit folgenden Code, der:

  • bewahrt den maximierten und normalen Zustand
  • ersetzt den minimierten Zustand durch die Standardposition
  • im Falle einer Änderung der Bildschirmgröße (abgetrennter Monitor, Fernverbindung,...) wird der Benutzer nicht in einen frustrierenden Zustand versetzt, wenn die Anwendung außerhalb des Bildschirms geöffnet ist.

    private void MyForm_Load(object sender, EventArgs e)
    {
        if (Properties.Settings.Default.IsMaximized)
            WindowState = FormWindowState.Maximized;
        else if (Screen.AllScreens.Any(screen => screen.WorkingArea.IntersectsWith(Properties.Settings.Default.WindowPosition)))
        {
            StartPosition = FormStartPosition.Manual;
            DesktopBounds = Properties.Settings.Default.WindowPosition;
            WindowState = FormWindowState.Normal;
        }
    }
    
    private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        Properties.Settings.Default.IsMaximized = WindowState == FormWindowState.Maximized;
        Properties.Settings.Default.WindowPosition = DesktopBounds;
        Properties.Settings.Default.Save();
    }

Benutzereinstellungen:

    <userSettings>
    <WindowsFormsApplication2.Properties.Settings>
        <setting name="WindowPosition" serializeAs="String">
            <value>0, 0, -1, -1</value>
        </setting>
        <setting name="IsMaximized" serializeAs="String">
            <value>False</value>
        </setting>
    </WindowsFormsApplication2.Properties.Settings>
</userSettings>

Hinweis: Die WindowsPosition ist absichtlich falsch, so dass beim ersten Start der Anwendung die Standardposition verwendet wird.

Beachten Sie, dass IntersectsWith ein Rechteck und nicht einen Punkt erwartet. Im Gegensatz zu anderen Antworten speichert diese Antwort also die DesktopBounds, nicht den Standort, in Properties.Settings.Default.WindowPosition

0 Stimmen

Bei mir hat es funktioniert, mit der Ausnahme, dass wenn das Fenster auf dem zweiten Bildschirm maximiert ist, es auf dem Hauptbildschirm wieder maximiert wird. Die Desktop-Grenzen sollten wiederhergestellt werden, bevor der Status festgelegt wird (wenn er sich überschneidet).

8voto

darksider474 Punkte 943

Ich habe verschiedene Methoden ausprobiert; das hier hat bei mir funktioniert. (In diesem Fall - beim ersten Start - wurden die Standardwerte noch nicht gespeichert, so dass das Formular die im Designer festgelegten Werte verwendet)

  1. Fügen Sie die Einstellungen zum Projekt hinzu (manuell - verlassen Sie sich nicht auf Visual Studio): Properties.Settings

  2. Fügen Sie den folgenden Code in Ihr Formular ein:

    private void Form1_Load(object sender, EventArgs e)
    {
        this.RestoreWindowPosition();
    }
    
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        this.SaveWindowPosition();
    }
    
    private void RestoreWindowPosition()
    {
        if (Settings.Default.HasSetDefaults)
        {
            this.WindowState = Settings.Default.WindowState;
            this.Location = Settings.Default.Location;
            this.Size = Settings.Default.Size;
        }
    }
    
    private void SaveWindowPosition()
    {
        Settings.Default.WindowState = this.WindowState;
    
        if (this.WindowState == FormWindowState.Normal)
        {
            Settings.Default.Location = this.Location;
            Settings.Default.Size = this.Size;
        }
        else
        {
            Settings.Default.Location = this.RestoreBounds.Location;
            Settings.Default.Size = this.RestoreBounds.Size;
        }
    
        Settings.Default.HasSetDefaults = true;
    
        Settings.Default.Save();
    }

3voto

anakic Punkte 2459

Wenn Sie die fabelhafte Open-Source-Bibliothek verwenden - Jot können Sie die mühsamen .settings-Dateien vergessen und einfach dies tun:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

Es gibt auch ein Nuget-Paket, und Sie können so ziemlich alles darüber konfigurieren, wie/wann/wo die Daten gespeichert werden.

Haftungsausschluss: Ich bin der Autor, aber die Bibliothek ist vollständig quelloffen (unter MIT-Lizenz).

0 Stimmen

Jot ist eine Amateurlösung. Lassen Sie Ihr Formular eine Position auf einem zweiten Monitor speichern, deaktivieren Sie den Monitor und Sie werden Ihr Formular nicht sehen. In manchen Fällen werden Sie es nie sehen, da die Windows-Schaltflächen zur Fensterpositionierung ignoriert werden können. Stellen Sie sich jetzt glückliche Kunden und Support-Teams vor. Ich habe nicht recherchiert, wie, aber es ändert das Layout von Formularen. WTF? Jot-Aktivitäten auf der Location-Eigenschaft werden ignoriert, wenn die StartPosition-Eigenschaft nicht auf Manual gesetzt ist. Und so weiter, und so weiter. Aber das ist ein netter Versuch. Lassen Sie es sein.

2 Stimmen

Hallo. Mehrere Displays (das Szenario mit unplugging) wird in der Github-Readme im Abschnitt "real world form/window tracking" sowie mit Callbacks für die Behandlung von Sonderfällen wie minimierte Windows angesprochen. Der obige Code ist zu Illustrationszwecken vereinfacht. Er ist auch ein bisschen veraltet. Wenn Sie bereit sind, ein Problem (oder einen Pull Request) für ein bestimmtes Szenario einzureichen, wäre das großartig.

0 Stimmen

Ich hätte es als Bibliothek und nicht als Rahmenwerk betrachten sollen. Ich werde die Readme lesen. Vielen Dank!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X