Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 201129
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T17:10:19+00:00 2026-05-11T17:10:19+00:00

I have made a class which a form can inherit from and it handles

  • 0

I have made a class which a form can inherit from and it handles form Location, Size and State. And it works nicely. Except for one thing:

When you maximize the application on a different screen than your main one, the location and size (before you maximized) gets stored correctly, but when it is maximized (according to its previous state) it is maximized on my main monitor. When I then restore it to normal state, it goes to the other screen where it was before. When I then maximize it again, it of course maximized on the correct screen.

So my question is… how can I make a form, when it is maximized, remember what screen it was maximized on? And how do I restore that when the form opens again?


Kind of complete solution to problem

I accepted the answer which had a very good tip about how to if on screen. But that was just part of my problem, so here is my solution:

On load

  1. First get stored Bounds and WindowState from whatever storage.
  2. Then set the Bounds.
  3. Make sure Bounds are visible either by Screen.AllScreens.Any(ø => ø.Bounds.IntersectsWith(Bounds)) or MdiParent.Controls.OfType<MdiClient>().First().ClientRectangle.IntersectsWith(Bounds).
    • If it doesn’t, just do Location = new Point();.
  4. Then set window state.

On closing

  1. Store WindowState.
  2. If WindowState is FormWindowState.Normal, then store Bounds, otherwise store RestoreBounds.

And thats it! =)

Some example code

So, as suggested by Oliver, here is some code. It needs to be fleshed out sort of, but this can be used as a start for whoever wants to:

PersistentFormHandler

Takes care of storing and fetching the data somewhere.

public sealed class PersistentFormHandler
{
    /// <summary>The form identifier in storage.</summary>
    public string Name { get; private set; }


    /// <summary>Gets and sets the window state. (int instead of enum so that it can be in a BI layer, and not require a reference to WinForms)</summary>
    public int WindowState { get; set; }


    /// <summary>Gets and sets the window bounds. (X, Y, Width and Height)</summary>
    public Rectangle WindowBounds { get; set; }


    /// <summary>Dictionary for other values.</summary>
    private readonly Dictionary<string, Binary> otherValues;


    /// <summary>
    /// Instantiates new persistent form handler.
    /// </summary>
    /// <param name="windowType">The <see cref="Type.FullName"/> will be used as <see cref="Name"/>.</param>
    /// <param name="defaultWindowState">Default state of the window.</param>
    /// <param name="defaultWindowBounds">Default bounds of the window.</param>
    public PersistentFormHandler(Type windowType, int defaultWindowState, Rectangle defaultWindowBounds)
        : this(windowType, null, defaultWindowState, defaultWindowBounds) { }

    /// <summary>
    /// Instantiates new persistent form handler.
    /// </summary>
    /// <param name="windowType">The <see cref="Type.FullName"/> will be used as base <see cref="Name"/>.</param>
    /// <param name="id">Use this if you need to separate windows of same type. Will be appended to <see cref="Name"/>.</param>
    /// <param name="defaultWindowState">Default state of the window.</param>
    /// <param name="defaultWindowBounds">Default bounds of the window.</param>
    public PersistentFormHandler(Type windowType, string id, int defaultWindowState, Rectangle defaultWindowBounds)
    {
        Name = string.IsNullOrEmpty(id) 
            ? windowType.FullName 
            : windowType.FullName + ":" + id;

        WindowState = defaultWindowState;
        WindowBounds = defaultWindowBounds;

        otherValues = new Dictionary<string, Binary>();
    }


    /// <summary>
    /// Looks for previously stored values in database.
    /// </summary>
    /// <returns>False if no previously stored values were found.</returns>
    public bool Load()
    {
        // See Note 1
    }

    /// <summary>
    /// Stores all values in database
    /// </summary>
    public void Save()
    {
        // See Note 2
    }

    /// <summary>
    /// Adds the given <paramref key="value"/> to the collection of values that will be
    /// stored in database on <see cref="Save"/>.
    /// </summary>
    /// <typeparam key="T">Type of object.</typeparam>
    /// <param name="key">The key you want to use for this value.</param>
    /// <param name="value">The value to store.</param>
    public void Set<T>(string key, T value)
    {
        // Create memory stream
        using (var s = new MemoryStream())
        {
            // Serialize value into binary form
            var b = new BinaryFormatter();
            b.Serialize(s, value);

            // Store in dictionary
            otherValues[key] = new Binary(s.ToArray());
        }
    }

    /// <summary>
    /// Same as <see cref="Get{T}(string,T)"/>, but uses default(<typeparamref name="T"/>) as fallback value.
    /// </summary>
    /// <typeparam name="T">Type of object</typeparam>
    /// <param name="key">The key used on <see cref="Set{T}"/>.</param>
    /// <returns>The stored object, or the default(<typeparamref name="T"/>) object if something went wrong.</returns>
    public T Get<T>(string key)
    {
        return Get(key, default(T));
    }

    /// <summary>
    /// Gets the value identified by the given <paramref name="key"/>.
    /// </summary>
    /// <typeparam name="T">Type of object</typeparam>
    /// <param name="key">The key used on <see cref="Set{T}"/>.</param>
    /// <param name="fallback">Value to return if the given <paramref name="key"/> could not be found.
    /// In other words, if you haven't used <see cref="Set{T}"/> yet.</param>
    /// <returns>The stored object, or the <paramref name="fallback"/> object if something went wrong.</returns>
    public T Get<T>(string key, T fallback)
    {
        // If we have a value with this key
        if (otherValues.ContainsKey(key))
        {
            // Create memory stream and fill with binary version of value
            using (var s = new MemoryStream(otherValues[key].ToArray()))
            {
                try
                {
                    // Deserialize, cast and return.
                    var b = new BinaryFormatter();
                    return (T)b.Deserialize(s);
                }
                catch (InvalidCastException)
                {
                    // T is not what it should have been
                    // (Code changed perhaps?)
                }
                catch (SerializationException)
                {
                    // Something went wrong during Deserialization
                }
            }
        }

        // Else return fallback
        return fallback;
    }
}

Note 1: In the load method you have to look for previously stored WindowState, WindowBounds and other values. We use SQL Server, and have a Window table with columns for Id, Name, MachineName (for Environment.MachineName), UserId, WindowState, X, Y, Height, Width. So for every window, you would have one row with WindowState, X, Y, Height and Width for each user and machine. In addition we have a WindowValues table which just has a foreign key to WindowId, a Key column of type String and a Value column of type Binary. If there is stuff that is not found, I just leave things default and return false.

Note 2: In the save method you then, of course do the reverse from what you do in the Load method. Creating rows for Window and WindowValues if they don’t exist already for the current user and machine.

PersistentFormBase

This class uses the previous class and forms a handy base class for other forms.

// Should have been abstract, but that makes the the designer crash at the moment...
public class PersistentFormBase : Form
{
    private PersistentFormHandler PersistenceHandler { get; set; }

    private bool handlerReady;

    protected PersistentFormBase()
    {
        // Prevents designer from crashing
        if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
        {
            Load += persistentFormLoad;
            FormClosing += persistentFormFormClosing;
        }
    }

    protected event EventHandler<EventArgs> ValuesLoaded;
    protected event EventHandler<EventArgs> StoringValues;

    protected void StoreValue<T>(string key, T value)
    {
        if (!handlerReady)
            throw new InvalidOperationException();
        PersistenceHandler.Set(key, value);
    }

    protected T GetValue<T>(string key)
    {
        if (!handlerReady)
            throw new InvalidOperationException();
        return PersistenceHandler.Get<T>(key);
    }

    protected T GetValue<T>(string key, T fallback)
    {
        if (!handlerReady)
            throw new InvalidOperationException();
        return PersistenceHandler.Get(key, fallback);
    }

    private void persistentFormLoad(object sender, EventArgs e)
    {
        // Create PersistenceHandler and load values from it
        PersistenceHandler = new PersistentFormHandler(GetType(), (int) FormWindowState.Normal, Bounds);
        PersistenceHandler.Load();
        handlerReady = true;

        // Set size and location
        Bounds = PersistenceHandler.WindowBounds;

        // Check if we have an MdiParent
        if(MdiParent == null)
        {
            // If we don't, make sure we are on screen
            if (!Screen.AllScreens.Any(ø => ø.Bounds.IntersectsWith(Bounds)))
                Location = new Point();
        }
        else
        {
            // If we do, make sure we are visible within the MdiClient area
            var c = MdiParent.Controls.OfType<MdiClient>().FirstOrDefault();
            if(c != null && !c.ClientRectangle.IntersectsWith(Bounds))
                Location = new Point();
        }

        // Set state
        WindowState = Enum.IsDefined(typeof (FormWindowState), PersistenceHandler.WindowState) ? (FormWindowState) PersistenceHandler.WindowState : FormWindowState.Normal;

        // Notify that values are loaded and ready for getting.
        var handler = ValuesLoaded;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }

    private void persistentFormFormClosing(object sender, FormClosingEventArgs e)
    {
        // Set common things
        PersistenceHandler.WindowState = (int) WindowState;
        PersistenceHandler.WindowBounds = WindowState == FormWindowState.Normal ? Bounds : RestoreBounds;

        // Notify that values will be stored now, so time to store values.
        var handler = StoringValues;
        if (handler != null)
            handler(this, EventArgs.Empty);

        // Save values
        PersistenceHandler.Save();
    }
}

And thats pretty much it. To use it, a form would just inherit from the PersistentFormBase. That would automatically take care of bounds and state. If anything else should be stored, like a splitter distance, you would listen for the ValuesLoaded and StoringValues events and in those use the GetValue and StoreValue methods.

Hope this can help someone! Please let me know if it does. And also, please provide some feedback if there is anything you think could be done better or something. I would like to learn =)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T17:10:20+00:00Added an answer on May 11, 2026 at 5:10 pm

    I found a solution to your problem by writing a little functio, that tests, if a poitn is on a connected screen.
    The main idea came from
    http://msdn.microsoft.com/en-us/library/system.windows.forms.screen(VS.80).aspx
    but some modifications were needed.

    public static bool ThisPointIsOnOneOfTheConnectedScreens(Point thePoint)
        {
            bool FoundAScreenThatContainsThePoint = false;
    
            for(int i = 0; i < Screen.AllScreens.Length; i++)
            {
                if(Screen.AllScreens[i].Bounds.Contains(thePoint))
                    FoundAScreenThatContainsThePoint = true;
            }
            return FoundAScreenThatContainsThePoint;
        }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 240k
  • Answers 240k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer I do it this way. Mark the left-border of the… May 13, 2026 at 7:11 am
  • Editorial Team
    Editorial Team added an answer Make sure the focus is on the editable div before… May 13, 2026 at 7:11 am
  • Editorial Team
    Editorial Team added an answer I use Emgu CV 2, and i wrote the same… May 13, 2026 at 7:11 am

Related Questions

I've made it a personal rule to inherit every UI control before using it.
Does anyone have any suggestions for a best practice or preferred way of rolling
Background I am trying to create a copy of a business object I have
I made some changes to an existing application that was previously just straight HTML

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.