SHARE
Facebook X Pinterest WhatsApp

Persistence of Window State and Appearance for .NET Applications

The process of building professional desktop applications includes many hidden tasks, such as the persistence of window state and appearance. This will introduce additional accessibility for such applications. This article describes a simple approach to do so. Sample applications written in C# and VB.NET. Let’s start with basic assumption about what are we intend to […]

Written By
thumbnail
CodeGuru Staff
CodeGuru Staff
Mar 5, 2004
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

The process of building professional desktop applications includes many hidden tasks, such as the persistence of window state and appearance. This will introduce additional accessibility for such applications. This article describes a simple approach to do so. Sample applications written in C# and VB.NET.

Let’s start with basic assumption about what are we intend to have. First of all, the main window size and position should be saved between sessions. Also, an application usually contains several panes, divided by splitters. The position of the splitters should be saved. If an application contains a list view, saving its columns width will be convenient too.

You can stop here if you don’t want to deal with the details of implementation. Simply include the UIPersistLib project from the source code for this article to your solution and add code from the following listing to your form. Also, please be sure to look at the end of this article.

using UIPersistLib;

public class MainFrame : System.Windows.Forms.Form
{
  ...
  private FormPersistence formPersistence;

  public MainFrame()
  {
    InitializeComponent();
    formPersistence =
    new FormPersistence(this, "SimpleAppCsharp\\Settings");
  }
}

Form Persistence Details

If you’re still here, I’ll try to explain the details. The FormPersistence class performed the subscription and handling of MainFrame events to save and restore the appropriate windows’ state and size. The main idea is saving the window size and position while it is restored (not minimized or maximized). The main window state must be saved as a separate value.

Handling the main window state

We can’t save the window’s state and position before closing it because we can lose information about the restored state if the window is maximized or minimized. Thus, let’s save it after changing:

private void MainFrame_Resize(object sender, System.EventArgs e)
{
  if(mainFrame.WindowState == FormWindowState.Normal)
  {
    Save();
  }
  else
  {
    SaveWindowState();
  }
}

private void MainFrame_Move(object sender, System.EventArgs e)
{
  if(mainFrame.WindowState == FormWindowState.Normal)
  {
    Save();
  }
  else
  {
    SaveWindowState();
  }
}

I encapsulated the writing and reading to the Registry into a ViewProfile class. This class can save Rectangles and single integer values.

Let’s examine the saving process. To prevent saving while initializating, provide the Boolean value restoreComplete. This value sets to false when restoring is started and to true when restoring is completed. If the window is maximized or minimized, we should not save bounds; we only need to save the window state.

public void Save()
{
  if(this.restoreComplete)
  {
    Profile.Write(Names.Bounds, mainFrame.DesktopBounds);
    SaveWindowState();
  }
}
private void SaveWindowState()
{
  Profile.Write(Names.WindowState, (int)mainFrame.WindowState);
}

Restoring performed while loading:

private void MainFrame_Load(object sender, System.EventArgs e)
{
  Restore();
}

public void Restore()
{
  this.restoreComplete = false;
  mainFrame.DesktopBounds = Profile.Read(Names.Bounds);
  mainFrame.WindowState =
    (FormWindowState)Profile.ReadInt(Names.WindowState);
  this.restoreComplete = true;
}

Persistence of splitters

To provide the persistence of splitting the pane’s size, we simply add code to the Save and Restore methods.

foreach(Control control in mainFrame.Controls)
{
  RestoreControl(control);
}

and

foreach(Control control in mainFrame.Controls)
{
  SaveControl(control);
}

Why the Controls collection? Because it contains all child controls regarding splitter levels. Saving the sizes of controls itself indirectly causes the saving of splitters. Also, we need to exclude saving of the toolbar and status bar.

private void RestoreControl(Control control)
{
  Type controlType = control.GetType();
  bool isToolBar   = (controlType == typeof(ToolBar));
  bool isStatusBar = (controlType == typeof(StatusBar));
  if(!isToolBar && !isStatusBar)
  {
    control.Bounds = Profile.Read(Names.Bounds + control.Name);
  }
}

private void SaveControl(Control control)
{
  Type controlType = control.GetType();
  bool isToolBar   = (controlType == typeof(ToolBar));
  bool isStatusBar = (controlType == typeof(StatusBar));
  if(!isToolBar && !isStatusBar)
  {
    Profile.Write(Names.Bounds + control.Name, control.Bounds);
  }
}

Persistence of columns in a list view

Finally, we can save list view columns. To do so, we need to provide additional code in the SaveControl and RestoreControl methods. We can examine the control type using Object.GetType() to match typeof(ListView) and when processing the ListView.Columns collection.

private void RestoreColumns(ListView listView)
{
  foreach(ColumnHeader column in listView.Columns)
  {
    column.Width = Profile.ReadInt(Names.Column + column.Index);
  }
}

private void SaveColumns(ListView listView)
{
  foreach(ColumnHeader column in listView.Columns)
  {
    Profile.Write(Names.Column + column.Index, column.Width);
  }
}

Where Is a Trick?

Thanks, DevPlanner, a tool for personal planning and estimating. It helps me preserve time for writing, while completing my primary work.

Recommended for you...

C# vs Java
Nicholas Rini
Mar 24, 2023
C# versus C
Nicholas Rini
Mar 22, 2023
Different Types of JIT Compilers in .NET
Tariq Siddiqui
Mar 17, 2023
Middleware in ASP.NET Core
Tariq Siddiqui
Mar 16, 2023
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.