Click here to Skip to main content
Click here to Skip to main content

Restore Form Position and Size in C#

, 23 Apr 2008
Rate this:
Please Sign up or sign in to vote.
Presents some logic and code to intelligently restore window sizes and positions.

FormPos1.png

Introduction

In this article, I am going to show you how to make two public static methods that will automate restoring WinForms' window positions, sizes, and states. So, let's say your user is running your C# Windows Forms program, and she maximizes it. This particular user is one of those who maximizes her windows. She closes the program at the end of the day, and the next time she opens it, she expects it to be maximized, just like she left it.

Background

The problem is that Microsoft and the Windows Forms toolkit do not make this as easy as it should be. You have to write this code yourself. And, this code must also take into account other users who position and size their windows differently.

Finally, this code needs some "sanity" checks--if a user accidentally moves the window 95% off of the visible screen, you will want to restore it to a more usable position on startup. Additionally, it is usually not desirable to start up a window in a minimized state. (Your user will wonder whatever happened to the program.)

Using the Code

You can call the code that processes your forms' positions in your Form constructor and in a FormClosing event. This will make the program start up with the saved position metrics, and will write out the metrics (geometry) when the program exits.

public TextWindow()
{
    // TextWindow is this form's name.
    // Your form will have a different name most likely.
    InitializeComponent();
    GeometryFromString(Properties.Settings.Default.WindowGeometry, this);
}

void TextWindow_FormClosing(object sender, FormClosingEventArgs e)
{
    // persist our geometry string.
    Properties.Settings.Default.WindowGeometry = GeometryToString(this);
    Properties.Settings.Default.Save();
}

How it Works

Here is some of the logic the functions use to ensure your forms are restored only when it is optimal for them to be restored.

General Technique

In this code, I have decided to use a static class and static methods. The C# program will use the Settings.settings file to store the actual coordinates and size. The coordinates and size are properties of the form itself, so the static methods I use will simply be utility methods that help the window use a standardized method of restoring its location and size.

The following method takes two parameters: a string storing the state, and the form you want to position based on that state string (thisWindowGeometry):

public static void GeometryFromString(string thisWindowGeometry, Form formIn)
{
    if (string.IsNullOrEmpty(thisWindowGeometry) == true)
    {
        return;
    }
    string[] numbers = thisWindowGeometry.Split('|');
    string windowString = numbers[4];
    if (windowString == "Normal")
    {
        Point windowPoint = new Point(int.Parse(numbers[0]),
            int.Parse(numbers[1]));
        Size windowSize = new Size(int.Parse(numbers[2]),
            int.Parse(numbers[3]));

        bool locOkay = GeometryIsBizarreLocation(windowPoint, windowSize);
        bool sizeOkay = GeometryIsBizarreSize(windowSize);

        if (locOkay == true && sizeOkay == true)
        {
            formIn.Location = windowPoint;
            formIn.Size = windowSize;
            formIn.StartPosition = FormStartPosition.Manual;
            formIn.WindowState = FormWindowState.Normal;
        }
        else if (sizeOkay == true)
        {
            formIn.Size = windowSize;
        }
    }
    else if (windowString == "Maximized")
    {
        formIn.Location = new Point(100, 100);
        formIn.StartPosition = FormStartPosition.Manual;
        formIn.WindowState = FormWindowState.Maximized;
    }
}

The above code contains logic to read in the geometry string (which another function, below, generates), and then test whether it can be used to position and resize the window. The booleans "locOkay" and "sizeOkay" each call a function that will return true if the location and size, respectively, are okay to restore.

Next, here's the function I use to see if the location (top and left corner point) of the window is okay to restore:

private static bool GeometryIsBizarreLocation(Point loc, Size size)
{
    bool locOkay;
    if (loc.X < 0 || loc.Y < 0)
    {
        locOkay = false;
    }
    else if (loc.X + size.Width > Screen.PrimaryScreen.WorkingArea.Width)
    {
        locOkay = false;
    }
    else if (loc.Y + size.Height > Screen.PrimaryScreen.WorkingArea.Height)
    {
        locOkay = false;
    }
    else
    {
        locOkay = true;
    }
    return locOkay;
}

The above function is called in GeometryFromString(). When we test that the size is okay to use, we use the following method:

private static bool GeometryIsBizarreSize(Size size)
{
    return (size.Height <= Screen.PrimaryScreen.WorkingArea.Height &&
        size.Width <= Screen.PrimaryScreen.WorkingArea.Width);
}

Basically, the size is okay whenever it is smaller than the screen. If the window is positioned partly off-screen, but it is small enough to fit on the screen, it is simply relocated, and the size doesn't change.

The next thing we do is serialize or persist a "geometry" string. This code does that:

public static string GeometryToString(Form mainForm)
{
    return mainForm.Location.X.ToString() + "|" +
        mainForm.Location.Y.ToString() + "|" +
        mainForm.Size.Width.ToString() + "|" +
        mainForm.Size.Height.ToString() + "|" +
        mainForm.WindowState.ToString();
}

The string returned by GeometryToString() can be passed to GeometryFromString() to retrieve the old window coordinates/size!

Conclusion

Put all the pieces together, and you will have forms that restore their position and size in a way that is optimal for your users. This article is one of about 70 articles on .NET at Dot Net Perls, including many articles related to this one.

License

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

About the Author

Samuel Allen
Web Developer Dot Net Perls
United States United States
I am a freelance software developer, with knowledge and experience with many .NET technologies, and also older technologies such as C and Perl. My site Dot Net Perls is fairly popular, at least from my perspective, and have generated thousands of hits. My web apps have been featured on Apple.com. I love writing about technologies, almost as much as I love programming and studying them. I am a big proponent of open source and think it is the way forward for programming. I want to show people the joy of programming and writing about programming and technical topics.

Comments and Discussions

 
GeneralMy vote of 5 Pinmembervidya_012-Jun-13 19:25 
GeneralMy vote of 5 PinmemberАslam Iqbal11-May-13 2:16 
GeneralMy vote of 1 PinmemberАslam Iqbal8-Mar-11 8:56 
GeneralRe: My vote of 1 PinmemberMember 995437011-May-13 2:06 
GeneralRe: My vote of 1 PinmemberАslam Iqbal11-May-13 2:17 
GeneralRe: My vote of 1 PinmemberАslam Iqbal11-May-13 2:27 
QuestionProperties.Settings? Pinmemberfooboo_020-Aug-09 0:20 
QuestionWhy do you want to invent the wheel? PinmemberMartin Radu2-Jul-08 3:22 
AnswerRe: Why do you want to invent the wheel? PinmemberParil3-Feb-10 10:39 
GeneralDual monitors support PinmemberOleg Shilo27-Apr-08 15:26 
GeneralRe: Dual monitors support PinmemberSamuel Allen27-Apr-08 18:57 
GeneralRe: Dual monitors support PinmemberJoe Sonderegger28-Apr-08 20:38 
GeneralRe: Dual monitors support PinmemberSamuel Allen28-Apr-08 20:59 
GeneralRe: Dual monitors support PinmemberAndrei Rinea30-Apr-08 9:37 
GeneralRe: Dual monitors support PinmemberJoe Sonderegger5-May-08 4:23 
GeneralRe: Dual monitors support PinmemberSamuel Allen12-Jun-08 19:39 
GeneralRe: Dual monitors support PinmemberLadislav Soukup29-Apr-08 0:03 
GeneralRe: Dual monitors support PinmemberOleg Shilo29-Apr-08 0:32 
GeneralRe: Dual monitors support PinmemberGWSyZyGy29-Apr-08 3:07 
GeneralRe: Dual monitors support PinmemberChrisTutty113826-Feb-10 19:12 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 23 Apr 2008
Article Copyright 2008 by Samuel Allen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid