Saving and Restoring Window Sizes and Positions
MM .NET provides the built-in ability to save and restore window sizes and positions per user and computer. The window sizes and positions are stored in a WindowSettings table in your database.
Follow the steps in the following sections to enable this functionality in your WPF application.
Creating the WindowSettings Table
- Since window settings are stored on a per-user basis, you must first add a User table to your database. For details, see the topic Step 1. Adding Security Tables to an Application Database
- To create the new WindowSettings table, you need to run the MMWindowSettings.sql script. Launch the SQL Server Management Studio.
- Press Ctrl+O to launch the Open File dialog. Navigate to the C:\Program Files (x86)\MM .NET Framework 2026\MM .NET Framework Wizards\Scripts directory, select the MMWindowSettings.sql file, and click the Open button.
This displays the MMWindowSettings.sql script file in the Query window.
- Go towards the top of the script file and look for the following:
use <Security Database>
Change <Security Database> to the name of your security database. For example:
use Northwind
- To run the script, press F5, or select the Execute Query button from the toolbar.
When the script is finished executing, you should have the new WindowSettings table in your database.
Creating the WindowSettingEntity in the Entity Data Model
- Right-click your project's Entity Data Model, select Update Model from Database.
- Generate a WindowSetting (not plural) object from the WindowSettings table.
- Rename the entity to WindowSettingEntity.
Creating the WindowSetting Business Object Classes
- Use the MM .NET Business Layer Generator to create new WindowSetting (not plural) business object classes from the WindowSettings table.
NOTE: On the Select Database Items page of the Business Layer Generator, select the Flags and WindowState entity properties Allow Empty Values check box, since these properties can contain a zero value
- After generating the WindowSetting business object classes, go to the WindowSetting.cs /.vb file, and add the following namespace reference to the top of the code file:
In C#:
using OakLeaf.MM.Main.Security;
In VB .NET:
Imports OakLeaf.MM.Main.Security
- Next, go to the WindowSetting.cs/.vb code file and change the base class to mmWindowSettingBase<WindowSettingEntity>.
In C#:
public partial class WindowSetting : mmWindowSettingBase<WindowSettingEntity>
In VB .NET:
Partial Public Class WindowSetting Inherits mmWindowSettingBase(Of WindowSettingEntity)
- In the WindowSetting.Partial.cs/.vb file, create overrides of the abstract GetWindowSetting() methods.
In C#:
public override WindowSettingEntity GetWindowSetting(string windowFullName, object userPK, object computerFK) { String cfk = computerFK.ToString(); IQueryable<WindowSettingEntity> query = from e in this.ObjectContext.WindowSettingEntities where (e.WindowFullName == windowFullName) && (e.UserFK == (int)userPK) && (e.ComputerFK == cfk) select e; return this.GetEntity(query); } public override WindowSettingEntity GetWindowSetting(string windowFullName, object userPK) { IQueryable<WindowSettingEntity> query = from e in this.ObjectContext.WindowSettingEntities where (e.WindowFullName == windowFullName) && (e.UserFK == (int)userPK) select e; return this.GetEntity(query); }In VB .NET:
Public Overrides Function GetWindowSetting(windowFullName As String, userPK As Object, computerFK As Object) As WindowSettingEntity Dim cfk As String = computerFK.ToString() Dim upk As Integer = Convert.ToInt32(userPK) Dim query As IQueryable(Of WindowSettingEntity) = From e In Me.ObjectContext.WindowSettingEntities Where e.WindowFullName = windowFullName _ And e.UserFK = upk _ And e.ComputerFK = cfk Select e Return Me.GetEntity(query) End Function Public Overrides Function GetWindowSetting(windowFullName As String, userPK As Object) As WindowSettingEntity Dim upk As Integer = Convert.ToInt32(userPK) Dim query As IQueryable(Of WindowSettingEntity) = From e In Me.ObjectContext.WindowSettingEntities Where e.WindowFullName = windowFullName _ And e.UserFK = upk Select e Return Me.GetEntity(query) End Function - In the WindowSetting.Partial.cs/.vb file's HookConstructor() method, set the database key to "EntityDataModelContainer".
In C#:
protected override void HookConstructor() { // Place code here to be executed when the business object instantiates this.DatabaseKey = "EntityDataModelContainer"; }In VB .NET:
Protected Overrides Sub HookConstructor() '' Place code here to be executed when the business object instantiates Me.DatabaseKey = "EntityDataModelContainer" End Sub
- In the WindowSettingEntity.cs/vb file, reference the following namespace AND implement the ImmWindowSettingEntity interface.
In C#:
using OakLeaf.MM.Main.Security; namespace Acme.OrderSystem.BusinessEF { /// <summary> /// Summary description for WindowSettingEntity. /// </summary> public partial class WindowSettingEntity : ABusinessEntity, ImmWindowSettingEntity { } }In VB .NET, it's quite a bit more work:
Imports OakLeaf.MM.Main.Security ''' <summary> ''' Summary description for WindowSettingEntity ''' </summary> Partial Public Class WindowSettingEntity Inherits ABusinessEntity Implements ImmWindowSettingEntity Private Property ImmWindowSettingEntity_Flags As Integer Implements ImmWindowSettingEntity.Flags Get Return Flags End Get Set(value As Integer) Flags = value End Set End Property Private Property ImmWindowSettingEntity_Length As Integer Implements ImmWindowSettingEntity.Length Get Return Length End Get Set(value As Integer) Length = value End Set End Property Private Property ImmWindowSettingEntity_MaxPosition As String Implements ImmWindowSettingEntity.MaxPosition Get Return MaxPosition End Get Set(value As String) MaxPosition = value End Set End Property Private Property ImmWindowSettingEntity_MinPosition As String Implements ImmWindowSettingEntity.MinPosition Get Return MinPosition End Get Set(value As String) MinPosition = value End Set End Property Private Property ImmWindowSettingEntity_NormalPosition As String Implements ImmWindowSettingEntity.NormalPosition Get Return NormalPosition End Get Set(value As String) NormalPosition = value End Set End Property Private Property ImmWindowSettingEntity_WindowFullName As String Implements ImmWindowSettingEntity.WindowFullName Get Return WindowFullName End Get Set(value As String) WindowFullName = value End Set End Property Private Property ImmWindowSettingEntity_WindowState As Integer Implements ImmWindowSettingEntity.WindowState Get Return WindowState End Get Set(value As Integer) WindowState = value End Set End Property End Class
Creating a Window Settings Manager Subclass
- In your WPF project (NOT your business object project), create a subclass of the WPF mmWindowSettingsManager, named WindowSettingsManager.
Note that you need to use/import the namespaces, and include the constructor shown below (change the last namespace to that of your business object project).
In C#:
using System.Windows; using OakLeaf.MM.Main.Security; using OakLeaf.MM.Main.WPF; using Acme.OrderSystem.BusinessEF; namespace Acme.OrderSystem.WPF { public class WindowSettingsManager : mmWindowSettingsManager { /// <summary> /// Constructor /// </summary> /// <param name="window"></param> public WindowsSettingsManager(Window window) : base(window) { } } }In VB .NET:
Imports System.Windows Imports OakLeaf.MM.Main.Security Imports OakLeaf.MM.Main.WPF Imports Acme.OrderSystem.BusinessEF Public Class WindowSettingsManager Inherits mmWindowSettingsManager Public Sub New(window As Window) MyBase.New(window) End Sub End Class - Add the following method to the new WindowSettingsManager class (adjust the code if your User PK is not an integer):
In C#:
/// <summary> /// Add the computer and user keys to the WindowsSettingEntity /// </summary> /// <param name="settingEntity"></param> /// <returns></returns> protected override bool HookPreSaveWindowState(ImmWindowSettingEntity settingEntity) { WindowSettingEntity settings = (WindowSettingEntity)settingEntity; settings.ComputerFK = mmAppWPF.ComputerPK.ToString(); settings.UserFK = (int)mmAppWPF.UserMgr.UserPK; return base.HookPreSaveWindowState(settingEntity); }In VB .NET:
Protected Overrides Function HookPreSaveWindowState(settingEntity As ImmWindowSettingEntity) As Boolean Dim Settings As WindowSettingEntity = CType(settingEntity, WindowSettingEntity) Settings.ComputerFK = mmAppWPF.ComputerPK.ToString() Settings.UserFK = Convert.ToInt32(mmAppWPF.UserMgr.UserPK) Return MyBase.HookPreSaveWindowState(settingEntity) End Function
Setting the Factory Methods
- In your WPF project's Factory class, add the following namespace references to the top of the code file (change the last namespace to that of your business object project):
In C#:
using System.Windows; using OakLeaf.MM.Main.Security; using Acme.OrderSystem.BusinessEF;
In VB .NET:
Imports System.Windows Imports OakLeaf.MM.Main.Security Imports Acme.OrderSystem.BusinessEF
- In your Factory class, add the following method that instantiates the WindowSetting business object:
In C#:
/// <summary> /// Factory method for WindowsSetting object /// </summary> /// <returns></returns> public override ImmWindowSetting CreateWindowSettingsObject() { return new WindowSetting(); }In VB .NET:
''' <summary> ''' Factory method for WindowSetting object ''' </summary> ''' <returns></returns> Public Overrides Function CreateWindowSettingsObject() As ImmWindowSetting Return New WindowSetting() End Function
- Next, add the following override method to your Factory class (it instantiates the new app-specific WindowsSettingManager):
/// <summary> /// Create an app-specific Window Settings Manager /// </summary> /// <param name="window"></param> /// <returns></returns> public override mmWindowSettingsManager CreateWindowSettingsManager(Window window) { return new WindowsSettingsManager(window); }In VB .NET:
''' <summary> ''' Creates an app-specific Window Settings Manager ''' </summary> ''' <param name="window"></param> ''' <returns></returns> Public Overrides Function CreateWindowSettingsManager(window As Window) As mmWindowSettingsManager Return New WindowSettingsManager(window) End Function
Setting the Current User
Only if you do not have security enabled in your app, you need to set the current user PK to the default user. To do this, go to your WPF project's AppWPF class, and in the constructor, add the following line of code.In C#:
/// <summary>
/// Constructor
/// </summary>
public AppWPF()
{
...
UserMgr.UserPK = 1; // Only set if security is not enabled
}In VB .NET:
Public Sub New()
...
UserMgr.UserPK = 1
End SubTurning On Windows Settings
To turn on saving and restoring Windows Settings, add a line of code to your WPF application object that sets the SaveWindowSettings property to true. For example:public AppWPF()
{
...
SaveWindowSettings = true;
}In VB .NET:
Public Sub New()
...
SaveWindowSettings = True
End Sub
© (c) 2026 Oak Leaf Enterprises, Inc., 1996-2026 • Updated: 02/10/26
Comment or report problem with topic
