Click here to Skip to main content
15,884,836 members
Articles / Desktop Programming / WPF
Article

Save and Restore the Location, Position and State of a WPF Window.

Rate me:
Please Sign up or sign in to vote.
4.22/5 (13 votes)
11 Oct 2006CPOL2 min read 73.9K   811   31   14
Presents a class that persists a WPF Window's state data using attached properties.

Introduction

I like the main window of my applications to "remember" its position, size and state. I want a no fuss method to add this functionality to my projects.

This article presents a class that provides this functionality using attached properties. The attached properties method provides a solution that does not involve subclassing the window. This solution does not require any code to be placed in the windows "code behind" file, hence keeping good separation of presentation and business layers. My solution is applied to my WPF project with the addition of a couple of lines of XAML.

This code was written and tested against the June 2006 CTP of the .NET Framework 3.0.

Using the code

One of the goals of the code is that it is easy to use. Because of this, I am going to start off by explaining how to use it and then follow up by explaining how it works.

  1. Create a new WinFX Windows Application with Visual Studio 2005 and add a reference to the Kingsmill.Windows.dll assembly.
  2. Open Window1.xaml and view the XAML; it should look like this:
    XML
    <Window x:Class="WindowsApplication1.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WindowsApplication1 "Height="300" Width="300">
        <Grid>
        </Grid>
    </Window>
  3. Edit Window1.xaml as per the following:

    XML
    <Window x:Class="WindowsApplication1.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:k="http://schemas.kingsmill.com/kingsmill/windows"
            Title="WindowsApplication1 "Height="300" Width="300"
            k:WindowSettings.Save="True">
        <Grid>
        </Grid>
    </Window>
  4. Run and stop the application, resizing and repositioning the window a few times. Note that the window size position and state is now "remembered".

How it works

The solution is implemented within the WindowSettings class.

What we are doing here is adding some behavior to the Avalon Window by adding some event handlers, but without subclassing the Window. The Avalon property system allows us to register a property that can be attached to any element; in our case the Window element. This is the same mechanism that allows us to put XAML code like DockPanel.Dock="Top" on a Button inside a DockPanel, even though Dock isn't a property that buttons know about. We can also make use of the ability to register for a callback when the property changes.

Here is our code that registers the Save property and registers the OnSaveInvalidated callback that is executed when the Save property value is changed.

C#
/// <summary>
/// Register the "Save" attached property and the "OnSaveInvalidated" callback
/// </summary>
public static readonly DependencyProperty SaveProperty
    = DependencyProperty.RegisterAttached("Save", typeof(bool), 
    typeof(WindowSettings), new FrameworkPropertyMetadata
        (new PropertyChangedCallback(OnSaveInvalidated)));

and here is the callback:

C#
/// <summary>
/// Called when Save is changed on an object.
/// </summary>
private static void OnSaveInvalidated(DependencyObject 
    dependencyObject, DependencyPropertyChangedEventArgs e)
{
    Window window = dependencyObject as Window;
    if (window != null)
    {
        if ((bool)e.NewValue)
        {
            WindowSettings settings = new WindowSettings(window);
            settings.Attach();
        }
    }
}

The method above is called in response to our XAML line:

XML
k:WindowSettings.Save="True"

Examining the OnSaveInvalidated method, we see that the dependencyObject is a Window, e.NewValue = true and a new WindowSettings object is created that wraps our Window. The Attach() method is then called which attaches our desired Load and Save behavior to the Avalon Window by attaching some event handlers whose responsibility it is to call the LoadWindowState() and SaveWindowState() methods when the Window is initialized and closed.

Well, that's about all there is to it. The rest of the code deals with saving and loading the settings and that has been discussed in other articles and is nothing new.

    License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


    Written By
    Web Developer
    Australia Australia
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    QuestionMultiple Monitors, but remoting in on a single monitor Pin
    openshac15-Apr-13 4:30
    openshac15-Apr-13 4:30 
    GeneralUpdate fixing bug with multiple monitors Pin
    Yet another user8-Jan-11 4:09
    Yet another user8-Jan-11 4:09 
    GeneralPersistId is obsolete Pin
    Phil J Pearson20-Nov-09 6:53
    Phil J Pearson20-Nov-09 6:53 
    GeneralThe attachable property 'Save' was not found in type 'WindowSettings' Pin
    Chuck14114-Jun-09 11:46
    Chuck14114-Jun-09 11:46 
    GeneralMultiple windows Pin
    Nigel Stratton15-May-09 9:08
    Nigel Stratton15-May-09 9:08 
    GeneralRe: Multiple windows Pin
    ehuna4-Jun-09 10:02
    ehuna4-Jun-09 10:02 
    AnswerRe: Multiple windows Pin
    super-e-28-Oct-10 2:04
    super-e-28-Oct-10 2:04 
    QuestionWhere does this save the settings? Pin
    JamesHurst21-Jan-08 14:11
    JamesHurst21-Jan-08 14:11 
    GeneralRe: Where does this save the settings? Pin
    Member 321449827-Apr-08 17:54
    Member 321449827-Apr-08 17:54 
    AnswerRe: Where does this save the settings? Pin
    Jani Giannoudis10-May-08 23:20
    Jani Giannoudis10-May-08 23:20 
    GeneralError (Using Orcas Beta1) Pin
    noirs213-Aug-07 8:11
    noirs213-Aug-07 8:11 
    QuestionHow does I get this window's attached property in Expression Blend Pin
    Jobi Joy15-May-07 21:59
    Jobi Joy15-May-07 21:59 
    GeneralSmall bug fix for maximizing windows Pin
    Erwyn7419-Dec-06 4:50
    Erwyn7419-Dec-06 4:50 
    GeneralWorks in .NET 3.0 RTM Pin
    Erwyn7419-Dec-06 4:22
    Erwyn7419-Dec-06 4:22 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.