tags:

views:

1567

answers:

5

Hello,

Basically when user resizes my application's window I want application to be same size when application is re-opened again.

At first I though of handling SizeChanged event and save Height and Width, but I think there must be easier solution.

Pretty simple problem, but I can not find easy solution to it.

+19  A: 

Save the values in the user.config file.

You'll need to create the value in the settings file - it should be in the Properties folder. Create five values:

  • Top of type double
  • Left of type double
  • Height of type double
  • Width of type double
  • 'Maximized' of type 'bool' - to hold whether the window is maximized or not. If you want to store more information then a different type or structure will be needed.

Initialise the first two to 0 and the second two to the default size of your application, and the last one to false.

In the constructor:

this.Top = Properties.Settings.Default.Top;
this.Left = Properties.Settings.Default.Left;
this.Height = Properties.Settings.Default.Height;
this.Width = Properties.Settings.Default.Width;
// Very quick and dirty - but it does the job
if (Properties.Settings.Default.Maximised)
{
    WindowState = WindowState.Maximized;
}

Create a Window_Closing event handler and add the following:

if (WindowState == WindowState.Maximized)
{
    // Use the RestoreBounds as the current values will be 0, 0 and the size of the screen
    Properties.Settings.Default.Top = RestoreBounds.Top;
    Properties.Settings.Default.Left = RestoreBounds.Left;
    Properties.Settings.Default.Height = RestoreBounds.Height;
    Properties.Settings.Default.Width = RestoreBounds.Width;
    Properties.Settings.Default.Maximised = true;
}
else
{
    Properties.Settings.Default.Top = this.Top;
    Properties.Settings.Default.Left = this.Left;
    Properties.Settings.Default.Height = this.Height;
    Properties.Settings.Default.Width = this.Width;
    Properties.Settings.Default.Maximised = false;
}

Properties.Settings.Default.Save();
ChrisF
Great answer. I would upvote again if I could.
Josh G
What if the application is installed under Program Files and the user is running as non-admin?
Kent Boogaart
Sorry - I meant user.config which is stored under C:\Documents and Settings\[user]\Local Settings\Application Data where the [User] should have access rights. I'll update the answer.
ChrisF
Actually, settings with scope "User" are not saved in the app.config file in Program Files, but in a user.config file in the user's application data directory. So it's not a problem...
Thomas Levesque
I realised the mistake in the original answer when I saw Kent's comment and corrected it - probably at the same time you were adding your comment!
ChrisF
Thank You for Your answer
Daniil Harik
Actually you can add "WindowState" to settings. Select type -> browse -> PresentationFramework -> System.Windows -> WindowState :)
MartyIX
FWIW, I do this from the size changed handler as well, in case of application crashes. They're rare with an unhandled exception processing, but why punish the user with lost size/location when they do mysteriously occur.
Tom
+11  A: 

Actually you don't need to use code-behind to do that (except for saving the settings). You can use a custom markup extension to bind the window size and position to the settings like this :

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="Window1"
        Height="{my:SettingBinding Height}"
        Width="{my:SettingBinding Width}"
        Left="{my:SettingBinding Left}"
        Top="{my:SettingBinding Top}">

You can find the code for this markup extension here : http://tomlev2.wordpress.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/

Thomas Levesque
I like this answer more than the chosen accepted answer. Well done.
mos
+9  A: 

While you can "roll your own" and manually save the settings somewhere, and in general it will work, it is very easy to not handle all of the cases correctly. It is much better to let the OS do the work for you, by calling GetWindowPlacement() at exit and SetWindowPlacement() at startup. It handles all of the crazy edge cases that can occur (multiple monitors, save the normal size of the window if it is closed while maximized, etc.) so that you don't have to.

This MSDN Sample shows how to use these with a WPF app. The sample isn't perfect (the window will start in the upper left corner as small as possible on first run, and there is some odd behavior with the Settings designer saving a value of type WINDOWPLACEMENT), but it should at least get you started.

Andy
If this answered your question, you should mark it as accepted so that this question no longer shows up as unanswered.
Andy
A: 

Markup extensions from Thomas are a good solution, but I think this is ideal for a behavior. I'll just wait a couple of weeks and somebody will creates one and post it to the Expression Community Gallery.

Sergey Aldoukhov
+2  A: 

Just wrote a blog entry detailing how to do this in a simple and robust manner. It uses the GetWindowPlacement and SetWindowPlacement functions mentioned by Andy, but with some of the odd behavior he mentioned cleaned up:

http://blogs.msdn.com/davidrickard/archive/2010/03/09/saving-window-size-and-location-in-wpf-and-winforms.aspx

RandomEngy