.NET / Windows Forms: remember windows size and location
Solution 1
You'll need to save the window location and size in your application settings. Here's a good C# article to show you how.
EDIT
You can save pretty much anything you want in the application settings. In the Type column of the settings grid you can browse to any .NET type. WindowState is in System.Windows.Forms and is listed as FormWindowState. There's also a property for FormStartPosition.
Solution 2
If you add this code to your FormClosing
event handler:
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();
It will save the current state.
Then add this code to your form's 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;
}
It will restore the last state.
It even remembers which monitor in a multi monitor set up the application was maximised to.
Solution 3
Previous solutions didn't work for me. After playing a while I ended up with following code which:
- preserves maximised and normal state
- replaces minimised state with default position
-
in case of screen size changes (detached monitor, remote connection,...) it will not get user into frustrating state with application open outside of screen.
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(); }
user settings:
<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>
Note: the WindowsPosition is intentionally wrong, so during first launch application will use default location.
Note that IntersectsWith expects a Rectangle, not a Point. So unlike other answers, this answer is saving the DesktopBounds, not Location, into Properties.Settings.Default.WindowPosition
Solution 4
I tried a few different methods; this is what ended up working for me. (In this case - on first launch - the defaults haven't been persisted yet, so the form will use the values set in the designer)
Add the settings to the project (manually - don't rely on visual studio):
-
Add the following code to your form:
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(); }
Solution 5
If you use the fabulous open source library - Jot, you can forget about the tedious .settings files and just do this:
public MainWindow()
{
InitializeComponent();
_stateTracker.Configure(this)
.IdentifyAs("MyMainWindow")
.AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
.RegisterPersistTrigger(nameof(Closed))
.Apply();
}
There's a Nuget package as well, and you can configure pretty much everything about how/when/where data is stored.
Disclaimer: I'm the author, but the library is completely open source (under MIT license).
Comments
-
clamp over 3 years
I have a Windows Forms application with a normal window. Now when I close the application and restart it, I want that the main window appears at the same location on my screen with the same size of the moment when it was closed.
Is there an easy way in Windows Forms to remember the screen location and window size (and if possible the window state) or does everything have to be done by hand?
-
clamp over 14 yearsthanks, that is a good article. only thing left is to remember the windowstate (maximized, minimized, ...) how can i put that one to the settings?
-
clamp over 14 yearsyes thanks. i didnt realize that you can browse to all types of .NET in these settings at first.
-
clamp over 14 yearsthanks! one more thing: if the window is maximized, how can i remember which monitor it is maximized on in a multi-monitor setup?
-
Walter over 14 yearsAdd the monitor id to the application settings as well.
-
clamp over 14 yearsthanks, but i couldnt find a way to get the monitor id. i only found the Screen object, but it doesnt seem to have something unique associated with it.
-
JohnForDummies over 14 yearsAgain, I'm sorry, I can't add a comment to the other thread... But Matt, by setting the location of the form, it will move it to the correct screen, and then you can set the WindowState to Maximized, etc, and it will be on the correct screen.
-
Don Kirkby about 13 years@clamp, I expect if you set the window position and then set the window state to maximized, it will maximize to cover whichever monitor it is in. If you record the window position and window state at shut down, and then apply the window position before the window state at start up, then it should maximize back where it was.
-
rob about 11 yearsFor those of you that haven't used Properties.Settings before you'll need to go into your project properties and go to the settings tab. Create a default settings file and add a property called Location and one called Size.
-
EricLaw almost 11 yearsYour location storage code fails if the form is Minimized. You need to also check for FormWindowState.Minimized too. Is "Maximised" a typo for "Maximized"?
-
ChrisF almost 11 years@EricLaw - "Maximised" is the name of the property. I suppose it should be "Maximized" for consistency. Re checking for "Minimized" - it was something I didn't have in the app I took this from.
-
Valamas over 10 years@rob: Cheers for the reminder on settings. ALSO: I tried and failed to move this code into a static helper class. Has anyone had such luck?
-
Glenn Maynard almost 10 yearsYou need to set WindowState after setting Location. Otherwise, the window will always be maximized on the default monitor, since the maximized location is based on Location at the time you set WindowState. That means that when the user maximizes it on his secondary monitor, it'll restore on the primary monitor instead.
-
CularBytes about 9 yearswhat is RestoreBounds? Does not exist, can't find a reference eather
-
ChrisF about 9 years@RageCompex -
RestoreBounds
is a property of theSystem.Windows.Forms.Form
class, so your app needs to be derive from that in order to use it. -
Rodrigo almost 7 yearsIT WORKED! But with some extra work for adding ApplicationSettings -> PropertyBinding thing (I'm not into .NET etc and all got too complex). More info below. In 2017, using a Windows Application targeting .NET Framework 4.5.2 I had to follow the steps pointed in this blog post to create the needed properties xldennis.wordpress.com/2010/03/19/…
-
it3xl over 4 yearsJot is amateur solution. Let your form to remember a position on a second monitor, disable the monitor and you won't see your form. In some cases you will never see it as Windows window positioning buttons may be ignored. Imagine happy customers and support teams now. I haven't researched how but it changes the layout of forms. WTF? Jot activities on the Location property will be ignored if StartPosition property isn't set to the Manual. And so on, and so on. But this is a nice try. Let it be.
-
anakic over 4 yearsHey. Multiple displays (the scenario with unplugging) is addressed in the github readme in the "real world form/window tracking" section as well as using callbacks for handling special cases like minimized windows. The above code is simplistic for illustration purposes. It's also a bit out of date. If you're up for submitting an issue (or a pull request) for any scenario in particular that'd be great.
-
it3xl over 4 yearsI should have been consider it as a library, not as a framework. I'll read the readme. Many thanks.
-
anakic over 4 yearsYeah, it's ~500 lines of code without whitespace and comments, so it's fairly small. I'd definitely call it a library, even though it can integrate with ioc containers and work as infrastructure.
-
TinyRacoon over 4 yearsGood solution. If you saved WindowState as type System.Windows.Forms.FormWindowState in settings it would saving having the max and min flags. X
-
Joan Charmant over 3 yearsThis one worked for me with the exception that if the window is maximized on the second screen it's restored maximized on the main screen. The desktop bounds should be restored before setting the state (if it intersects).