Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Article

Restore Form Position and Size in C#

Rate me:
Please Sign up or sign in to vote.
3.90/5 (18 votes)
23 Apr 2008CPOL3 min read 142K   41   23
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.

C#
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):

C#
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:

C#
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:

C#
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:

C#
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)


Written By
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

 
QuestionOutstanding, simple and clear. 5 Pin
Michael B Pliam19-Apr-16 12:55
Michael B Pliam19-Apr-16 12:55 
GeneralMy vote of 5 Pin
vidya_012-Jun-13 19:25
vidya_012-Jun-13 19:25 
GeneralMy vote of 5 Pin
Аslam Iqbal11-May-13 2:16
professionalАslam Iqbal11-May-13 2:16 
GeneralMy vote of 1 Pin
Аslam Iqbal8-Mar-11 8:56
professionalАslam Iqbal8-Mar-11 8:56 
GeneralRe: My vote of 1 Pin
TobyCodes11-May-13 2:06
TobyCodes11-May-13 2:06 
GeneralRe: My vote of 1 Pin
Аslam Iqbal11-May-13 2:17
professionalАslam Iqbal11-May-13 2:17 
GeneralRe: My vote of 1 Pin
Аslam Iqbal11-May-13 2:27
professionalАslam Iqbal11-May-13 2:27 
QuestionProperties.Settings? Pin
fooboo_020-Aug-09 0:20
fooboo_020-Aug-09 0:20 
AnswerRe: Properties.Settings? Pin
şenol eker18-Oct-21 10:51
şenol eker18-Oct-21 10:51 
QuestionWhy do you want to invent the wheel? Pin
Martin Radu2-Jul-08 3:22
Martin Radu2-Jul-08 3:22 
AnswerRe: Why do you want to invent the wheel? Pin
Paril3-Feb-10 10:39
Paril3-Feb-10 10:39 
It depends on how you look at it though, because in reality his method of saving the string in one setting is better than three/four settings. Also, settings are converted to and back from strings anyways, storing it in a string in the first place isn't such a bad idea.
GeneralDual monitors support PinPopular
Oleg Shilo27-Apr-08 15:26
Oleg Shilo27-Apr-08 15:26 
GeneralRe: Dual monitors support Pin
Samuel Allen27-Apr-08 18:57
Samuel Allen27-Apr-08 18:57 
GeneralRe: Dual monitors support Pin
Joe Sonderegger28-Apr-08 20:38
Joe Sonderegger28-Apr-08 20:38 
GeneralRe: Dual monitors support Pin
Samuel Allen28-Apr-08 20:59
Samuel Allen28-Apr-08 20:59 
GeneralRe: Dual monitors support Pin
Andrei Ion Rînea30-Apr-08 9:37
Andrei Ion Rînea30-Apr-08 9:37 
GeneralRe: Dual monitors support Pin
Joe Sonderegger5-May-08 4:23
Joe Sonderegger5-May-08 4:23 
GeneralRe: Dual monitors support Pin
Samuel Allen12-Jun-08 19:39
Samuel Allen12-Jun-08 19:39 
GeneralRe: Dual monitors support Pin
Ladislav Soukup29-Apr-08 0:03
Ladislav Soukup29-Apr-08 0:03 
GeneralRe: Dual monitors support Pin
Oleg Shilo29-Apr-08 0:32
Oleg Shilo29-Apr-08 0:32 
GeneralRe: Dual monitors support Pin
GWSyZyGy29-Apr-08 3:07
GWSyZyGy29-Apr-08 3:07 
GeneralRe: Dual monitors support Pin
ChrisTutty113826-Feb-10 19:12
ChrisTutty113826-Feb-10 19:12 
GeneralRe: Dual monitors support Pin
MrBjorn19-Mar-18 23:44
MrBjorn19-Mar-18 23:44 

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.