Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to record window position in Windows Forms application settings

Tags:

It seems like a standard requirement: next time the user launches the application, open the window in the same position and state as it was before. Here's my wish list:

  • Window position same as it was
    • Unless the screen has resized and the old position is now off screen.
  • Splitters should retain their position
  • Tab containers should retain their selection
  • Some dropdowns should retain their selection
  • Window state (maximize, minimize, normal) is the same as it was.
    • Maybe you should never start minimized, I haven't decided.

I'll add my current solutions as an answer along with the limitations.

like image 713
Don Kirkby Avatar asked Sep 19 '08 21:09

Don Kirkby


People also ask

Which window is used to set the position of form at run time view?

By simply dragging the miniature form to a particular location, the position of a form can be set in the “Form Layout” window.

How can I bring my application window to the front?

When the user has the program minimized and presses F3 a global hook keys gets the press and translation window should be made and brought to front.

How can you save the desired properties of Windows Forms application?

A simple way is to use a configuration data object, save it as an XML file with the name of the application in the local Folder and on startup read it back.


2 Answers

My other option is to write more custom code around the application settings and execute it on formLoad and formClosed. This doesn't use data binding.

Drawbacks:

  • More code to write.
  • Very fiddly. The order you set the properties on formLoad is confusing. For example, you have to make sure you've set the window size before you set the splitter distance.

Right now, this is my preferred solution, but it seems like too much work. To reduce the work, I created a WindowSettings class that serializes the window location, size, state, and any splitter positions to a single application setting. Then I can just create a setting of that type for each form in my application, save on close, and restore on load.

I posted the source code, including the WindowSettings class and some forms that use it. Instructions on adding it to a project are included in the WindowSettings.cs file. The trickiest part was figuring out how to add an application setting with a custom type. You choose Browse... from the type dropdown, and then manually enter the namespace and class name. Types from your project don't show up in the list.

Update: I added some static methods to simplify the boilerplate code that you add to each form. Once you've followed the instructions for adding the WindowSettings class to your project and creating an application setting, here's an example of the code that has to be added to each form whose position you want to record and restore.

    private void MyForm_FormClosing(object sender, FormClosingEventArgs e)     {         Settings.Default.CustomWindowSettings = WindowSettings.Record(             Settings.Default.CustomWindowSettings,             this,              splitContainer1);     }      private void MyForm_Load(object sender, EventArgs e)     {         WindowSettings.Restore(             Settings.Default.CustomWindowSettings,              this,              splitContainer1);     } 
like image 185
Don Kirkby Avatar answered Oct 10 '22 07:10

Don Kirkby


The sample below shows how I do it

  • SavePreferences is called when closing the form and saves the form's size, and a flag indicating if it's maximized (in this version I don't save if it's minimized - it will come back up restored or maximized next time).

  • LoadPreferences is called from OnLoad.

  • First save the design-time WindowState and set it to Normal. You can only successfully set the form size if it's WindowState is Normal.

  • Next restore the Size from your persisted settings.

  • Now make sure the form fits on your screen (call to FitToScreen). The screen resolution may have changed since you last ran the application.

  • Finally set the WindowState back to Maximized (if persisted as such), or to the design-time value saved earlier.

This could obviously be adapted to persist the start position and whether the form was minimized when closed - I didn't need to do that. Other settings for controls on your form such as splitter position and tab container are straightforward.

private void FitToScreen() {     if (this.Width > Screen.PrimaryScreen.WorkingArea.Width)     {         this.Width = Screen.PrimaryScreen.WorkingArea.Width;     }     if (this.Height > Screen.PrimaryScreen.WorkingArea.Height)     {         this.Height = Screen.PrimaryScreen.WorkingArea.Height;     } }    private void LoadPreferences() {     // Called from Form.OnLoad      // Remember the initial window state and set it to Normal before sizing the form     FormWindowState initialWindowState = this.WindowState;     this.WindowState = FormWindowState.Normal;     this.Size = UserPreferencesManager.LoadSetting("_Size", this.Size);     _currentFormSize = Size;     // Fit to the current screen size in case the screen resolution     // has changed since the size was last persisted.     FitToScreen();     bool isMaximized = UserPreferencesManager.LoadSetting("_Max", initialWindowState == FormWindowState.Maximized);     WindowState = isMaximized ? FormWindowState.Maximized : FormWindowState.Normal; } private void SavePreferences() {     // Called from Form.OnClosed     UserPreferencesManager.SaveSetting("_Size", _currentFormSize);     UserPreferencesManager.SaveSetting("_Max", this.WindowState == FormWindowState.Maximized);     ... save other settings } 

x

like image 44
Joe Avatar answered Oct 10 '22 05:10

Joe