Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I finally came up with a Form subclass that solves this, once and for all. To use it:</p> <ol> <li>Inherit from RestorableForm instead of Form.</li> <li>Add a binding in (ApplicationSettings) -> (PropertyBinding) to WindowRestoreState.</li> <li>Call Properties.Settings.Default.Save() when the window is about to close.</li> </ol> <p>Now window position and state will be remembered between sessions. Following the suggestions from other posters below, I included a function ConstrainToScreen that makes sure the window fits nicely on the available displays when restoring itself.</p> <h3>Code</h3> <pre><code>// Consider this code public domain. If you want, you can even tell // your boss, attractive women, or the other guy in your cube that // you wrote it. Enjoy! using System; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace Utilities { public class RestorableForm : Form, INotifyPropertyChanged { // We invoke this event when the binding needs to be updated. public event PropertyChangedEventHandler PropertyChanged; // This stores the last window position and state private WindowRestoreStateInfo windowRestoreState; // Now we define the property that we will bind to our settings. [Browsable(false)] // Don't show it in the Properties list [SettingsBindable(true)] // But do enable binding to settings public WindowRestoreStateInfo WindowRestoreState { get { return windowRestoreState; } set { windowRestoreState = value; if (PropertyChanged != null) { // If anybody's listening, let them know the // binding needs to be updated: PropertyChanged(this, new PropertyChangedEventArgs("WindowRestoreState")); } } } protected override void OnClosing(CancelEventArgs e) { WindowRestoreState = new WindowRestoreStateInfo(); WindowRestoreState.Bounds = WindowState == FormWindowState.Normal ? Bounds : RestoreBounds; WindowRestoreState.WindowState = WindowState; base.OnClosing(e); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (WindowRestoreState != null) { Bounds = ConstrainToScreen(WindowRestoreState.Bounds); WindowState = WindowRestoreState.WindowState; } } // This helper class stores both position and state. // That way, we only have to set one binding. public class WindowRestoreStateInfo { Rectangle bounds; public Rectangle Bounds { get { return bounds; } set { bounds = value; } } FormWindowState windowState; public FormWindowState WindowState { get { return windowState; } set { windowState = value; } } } private Rectangle ConstrainToScreen(Rectangle bounds) { Screen screen = Screen.FromRectangle(WindowRestoreState.Bounds); Rectangle workingArea = screen.WorkingArea; int width = Math.Min(bounds.Width, workingArea.Width); int height = Math.Min(bounds.Height, workingArea.Height); // mmm....minimax int left = Math.Min(workingArea.Right - width, Math.Max(bounds.Left, workingArea.Left)); int top = Math.Min(workingArea.Bottom - height, Math.Max(bounds.Top, workingArea.Top)); return new Rectangle(left, top, width, height); } } } </code></pre> <h3>Settings Bindings References</h3> <ul> <li><a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.settingsbindableattribute.aspx" rel="noreferrer">SettingsBindableAttribute</a></li> <li><a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx" rel="noreferrer">INotifyPropertyChanged</a></li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload