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

Save and restore Form position and layout with this component

Rate me:
Please Sign up or sign in to vote.
4.71/5 (52 votes)
25 Feb 20042 min read 136K   3.6K   81   24
A component that allows to save and restore layout of any Form without coding.

Sample Image - Tester.gif

Introduction

Finally there is no more need to write even a single line of code to persist your window's size, location and state. This article presents a component, which automatically saves these properties to the system registry. In addition, this component allows to save the location and size of any control on a form, including splitters and docked controls.

When the RealPosition component is added to a Form, it gives 2 new boolean properties to visible controls. The first property, RestoreLocation, indicates whether the control's position and size should be persisted. If set to true, the control's position and size are saved when the main form closes. The position and size are restored when the .Load event occurs. The second property, RestoreColumnsWidth, applies only to ListView and inherited controls. It allows saving widths of all columns.

Using the code

Add RestoreState.dll to your designer toolbox. Put the RealPosition component into your form. You will see something like this:

Control testing application

For the main form, the RestoreLocation will be set to true by default. Thus, the position and size of the form will be persisted by default. You can set RestoreLocation=true manually for any other controls which you want to persist.

The data is stored in the system registry. Registry key is represented by realPosition1.RegistryPath. You might want to configure this property for your application.

How it works

RealPosition implements IExtenderProvider, which allows it to "provide" new properties to existing controls at design-time.

C#
[ProvideProperty("RestoreLocation", typeof(Control))] 
[ProvideProperty("RestoreColumnsWidth", typeof(ListView))] 
public class RealPosition : Component, IExtenderProvider 
{ 
    // implementation
}

When RestoreLocation is set to true, the development environment generates the following code, which gives realPosition1 references to objects in InitializeComponent().

C#
this.realPosition1.SetRestoreLocation(this.panel11, true);         
................
this.realPosition1.SetRestoreLocation(this.panel12, true);
................
this.realPosition1.SetRestoreLocation(this, true);

RealPosition attaches to .Load and .Closed events in SetRestoreLocation. It performs save and restore operations in the event handler.

C#
f.Closed += new System.ComponentModel.CancelEventHandler(OnClosed);
f.Load += new System.EventHandler(OnLoad);

Known issues

Suppose that a ListView is contained on a Panel and has Left and Right Anchors enabled. In that case, ListView will resize whenever Panel is resized. On startup, RealPosition resizes all linked controls. First, it restores the size of ListView. Then it restores the Panel. Resizing Panel causes ListView to be resized again, thus giving wrong result. Solution: do not enable RestoreLocation in child controls.

Conclusion

This is my first post, so please rate this article and let me know what you think. I hope a few people will find this class useful. Have fun with it...

Updates

15 February 2004

Now the RealPosition component can be placed on any UserControl. Many thanks to Paul J for his suggestion. The following code finds the parent Form of the UserControl and then attaches to its .Closed event.

C#
while(!(parent is Form) && parent != null)
{
    parent = parent.Parent;
} 
m_parentForm = parent as Form;
if(m_parentForm != null)
{
    m_parentForm.Closed += new EventHandler(OnClosed);
}

Another update prevents restoration of the Form's position, if the Form is located outside of the visible area of the screen.

A ComponentDesigner class is now used to retrieve a reference to a container Control. Thanks to Alvaro Mendez for this technique.

The solution file and compiled RestoreState.dll now require VS2003 and .NET Framework 1.1

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


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

Comments and Discussions

 
GeneralSmall change for app with multiple forms Pin
hatton17-May-07 23:31
hatton17-May-07 23:31 
GeneralRealPosition, DataGridView Extensions Pin
Martinus Keller14-May-07 3:40
Martinus Keller14-May-07 3:40 
GeneralHelp needed Pin
pankaj0dm7-May-07 3:20
pankaj0dm7-May-07 3:20 
GeneralSave/restore datagrid settings Pin
AndrusM27-Nov-06 8:29
AndrusM27-Nov-06 8:29 
General.NET 2.0 version Pin
JohnZonie25-Nov-06 5:29
JohnZonie25-Nov-06 5:29 
GeneralWorks fine in vs 2005 Pin
szuwar19798-May-06 9:23
szuwar19798-May-06 9:23 
GeneralCongratulations Pin
mig1630-Apr-06 18:10
mig1630-Apr-06 18:10 
GeneralHELP Pin
mattp1214846-Dec-04 12:52
mattp1214846-Dec-04 12:52 
Generalhello Igor Pin
Member 120031424-Sep-04 20:25
Member 120031424-Sep-04 20:25 
QuestionHas anbody converted to vb.net? Pin
sasijrao8-Sep-04 5:35
sasijrao8-Sep-04 5:35 
QuestionWhat about when the screen resolution changes Pin
RodgerB12-Jul-04 9:18
RodgerB12-Jul-04 9:18 
GeneralShowdialog error Pin
shyless12-Apr-04 23:43
shyless12-Apr-04 23:43 
GeneralComplex controls issue... Pin
Anonymous26-Feb-04 6:57
Anonymous26-Feb-04 6:57 
GeneralModify for UserControl composite controls Pin
lilGennie5-Feb-04 7:43
lilGennie5-Feb-04 7:43 
GeneralRe: Modify for UserControl composite controls Pin
I G 19814-Feb-04 23:50
I G 19814-Feb-04 23:50 
GeneralMaximized form restore size/position not saved Pin
QDefender2-Oct-03 6:15
QDefender2-Oct-03 6:15 
GeneralRe: Thank you Pin
I G 1982-Oct-03 10:14
I G 1982-Oct-03 10:14 
QuestionUsing a file instead of registry? Pin
Eto25-Sep-03 20:10
Eto25-Sep-03 20:10 
AnswerRe: Using a file instead of registry? Pin
I G 19825-Sep-03 20:37
I G 19825-Sep-03 20:37 
GeneralRe: Using a file instead of registry? Pin
Attila Hajdrik25-Sep-03 21:10
Attila Hajdrik25-Sep-03 21:10 
AnswerRe: Using a file instead of registry? Pin
Uwe Keim25-Sep-03 21:09
sitebuilderUwe Keim25-Sep-03 21:09 
GeneralRe: Using a file instead of registry? Pin
I G 19826-Sep-03 2:27
I G 19826-Sep-03 2:27 
GeneralRe: Using a file instead of registry? Pin
Uwe Keim26-Sep-03 3:01
sitebuilderUwe Keim26-Sep-03 3:01 
GeneralRe: Using a file instead of registry? Pin
nycos6224-Mar-16 1:54
nycos6224-Mar-16 1:54 
replace RealPosition.cs by this , and add in your designer.cs this line :

// 
// realPosition1
// 
this.realPosition1.Parent = this;            
this.realPosition1.RegistryPath = "Software\\Company\\SoftwareName\\";
this.realPosition1.SaveDirectory = "RoamingProfileSubDirectory\\sub2\\";


if this line is not in the designer.cs, it will save/load in registry

C#
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using Microsoft.Win32;
using System.ComponentModel.Design;
using System.Xml;

namespace RestoreState
{
	/// <summary>
	/// Component class that allows saving and restoring position and size of 
	/// any System.Windows.Froms.Control, contained on a Form or UserControl.
	/// It does not save/restore Form position in minimized state.
	/// For ListView controls it can save/restore widths of colums.
	/// </summary>
	[Designer(typeof(RealPositionDesigner))]	
	[ToolboxItem(true)]
	[ToolboxBitmap(typeof(RealPosition))]
	[ProvideProperty("RestoreLocation", typeof(Control))]
	[ProvideProperty("RestoreColumnsWidth", typeof(ListView))]
	public class RealPosition : Component, IExtenderProvider
	{
		private System.ComponentModel.Container components = null;
		private string m_RegPath;
		private string m_subRegPath;
		private Hashtable m_properties;
		private Control m_parent = null;
		private Form m_parentForm = null;
        public bool SaveInFile
        {
            get { return !string.IsNullOrEmpty( SaveDirectory );}
        }
        private string m_SaveDirectory;

		#region RealPosition Constructors
		public RealPosition()
		{
			m_RegPath = @"Software\RestoreState\RealPosition"; // default key to store data
			m_properties = new Hashtable();
		}
		
		public RealPosition(IContainer parent) : this()
		{
			parent.Add(this);
			InitializeComponent();
		}
		#endregion

		#region Indexer
		// indexer is provided to simplify implementation of properties
		public Properties this[object o]
		{
			get
			{
				return EnsureExists(o);
			}
			set
			{
				Properties p = EnsureExists(o);
				p = value;
			}
		}
		private Properties EnsureExists(object key)
		{
			Properties p = (Properties)m_properties[key];
			if(p == null)
			{
				p = new Properties(key);
				m_properties[key] = p;
			}
			return p;
		}
		#endregion

		#region Properties

        [Category("RealPosition")]
        [DefaultValue(@"")]
        [Description(@"Roaming profile sub Directory path")]
        public string SaveDirectory 
        {
            get { return m_SaveDirectory; }
            set { m_SaveDirectory = value;}
        }

		[Category("RealPosition")]
		[DefaultValue(@"Software\RestoreState\RealPosition")]
		[Description(@"Registry path to store controls' positions")]
		public string RegistryPath
		{
			get {return m_RegPath;}
			set {m_RegPath = value;}
		}

		[Browsable(false)]
		public Control Parent
		{
			get
			{
				return m_parent;
			}
			set
			{
				if(m_parent == value) return;

				// unload current handlers
				if(!this.DesignMode)
				{
					Form f = m_parentForm;
					if(f != null)
					{
						f.Closed -= new EventHandler(OnClosed);
						f.Load -= new EventHandler(OnLoad);
					}
				}

				m_parent = value;

				// attach handlers
				if(!this.DesignMode)
				{
					if(m_parent is Form) 
					{
						m_parentForm = (Form)m_parent;
						m_parentForm.Load += new EventHandler(OnLoad);
					}
					else if(m_parent is UserControl)
					{
						UserControl u = (UserControl)m_parent;
						u.Load += new EventHandler(OnLoad);
					}
				}
			}
		}
		#endregion

		#region Extended Properties

		[Description("Save and restore Control's position and size")]
		[Category("RealPosition")]
		public bool GetRestoreLocation(Control c)
		{
			return this[c].RestoreLocation;
		}
		public void SetRestoreLocation(Control c, bool val)
		{
			this[c].RestoreLocation = val;
		}
		private bool ShouldSerializeRestoreLocation(Control c)
		{
			if(this[c].RestoreLocation == true) 
				return true;
			else 
				return false;
		}
		private void ResetRestoreLocation(Control c)
		{
			// by default Restore the location of the main Form 
			// by default do not restore location of UserControl
			this[c].RestoreLocation = (c is Form); 
		}

		[Description("Save and restore ListView's column widths")]
		[Category("RealPosition")]
		public bool GetRestoreColumnsWidth(Control c)
		{
			return this[c].RestoreColumnsWidth;
		}
		public void SetRestoreColumnsWidth(Control c, bool val)
		{
			this[c].RestoreColumnsWidth = val;
		}
		private bool ShouldSerializeRestoreColumnsWidth(Control c)
		{
			return this[c].RestoreColumnsWidth;
		}

		#endregion

		#region Event Handlers

        public void LoadProperties()
        {
            if (SaveInFile)
            {
                // restore state/position
                m_parent.SuspendLayout();
                foreach (DictionaryEntry property in m_properties)
                {
                    Properties p = (Properties)property.Value;
                    string regpath = m_subRegPath + p.m_subRegPath;

                    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), SaveDirectory));
                    if (di.Exists)
                    {                        
                        if (p.RestoreLocation == true) // Restore only if RestoreLocation is True
                        {
                            XmlDocument xmlDoc = new XmlDocument();
                            try
                            {
                                string path = di.FullName + regpath.TrimEnd('\\') + @"\data.xml";
                                xmlDoc.Load(path.Replace(@"\\",@"\"));
                            }
                            catch { Console.WriteLine(di.FullName + regpath.TrimEnd('\\') + @"\data.xml" + " not found"); }
                            
                            if (xmlDoc != null)
                            {
                                LoadControlLocationAndState(xmlDoc, p);
                            }
                        }
                        if (p.RestoreColumnsWidth == true)
                        {
                            string regpath_headers = regpath + @"\ColumnHeaders";
                            XmlDocument xmlDoc = new XmlDocument();
                            try
                            {
                                string apath = di.FullName + regpath_headers.TrimEnd('\\').Replace(@"\\", @"\") + @"\data.xml";

                                xmlDoc.Load(apath.Replace(@"\\", @"\"));
                            }
                            catch {
                                string apath = di.FullName + regpath_headers.TrimEnd('\\').Replace(@"\\", @"\") + @"\data.xml";
                                Console.WriteLine(apath.Replace(@"\\", @"\") + " not found"); 
                            }
                            if (xmlDoc != null)
                            {
                                LoadListViewColumns(xmlDoc, p);
                            }
                        }
                    }
                }
                m_parent.ResumeLayout();
            }
            else
            {
                // restore state/position
                m_parent.SuspendLayout();
                foreach (DictionaryEntry property in m_properties)
                {
                    Properties p = (Properties)property.Value;
                    string regpath = m_RegPath + m_subRegPath + p.m_subRegPath;
                    if (p.RestoreLocation == true) // Restore only if RestoreLocation is True
                    {
                        RegistryKey key = Registry.CurrentUser.OpenSubKey(regpath);

                        if (key != null)
                        {
                            LoadControlLocationAndState(key, p);
                        }
                    }
                    if (p.RestoreColumnsWidth == true)
                    {
                        string regpath_headers = regpath + @"\ColumnHeaders";
                        RegistryKey key_headers = Registry.CurrentUser.OpenSubKey(regpath_headers);
                        LoadListViewColumns(key_headers, p);
                    }
                }
                m_parent.ResumeLayout();
            }
        }

        public void SaveProperties()
        {
            if (SaveInFile)
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), SaveDirectory));
                if (di.Exists == false) { di.Create(); }

                foreach (DictionaryEntry property in m_properties)
                {
                    Properties p = (Properties)property.Value;
                    string regpath = m_subRegPath + p.m_subRegPath;
                    string FileName = di.FullName + regpath.TrimEnd('\\') + @"\data.xml";

                    System.IO.DirectoryInfo di2 = new System.IO.DirectoryInfo(System.IO.Path.GetDirectoryName(FileName));
                    if (di2.Exists == false) { di2.Create(); }
                                        
                    /*RegistryKey key = Registry.CurrentUser.CreateSubKey(regpath);*/
                    if (p.RestoreLocation == true) // Save only if RestoreLocation is True
                    {
                        XmlDocument xmlDoc = new XmlDocument();
                        XmlElement elem = xmlDoc.CreateElement("data");
                        xmlDoc.AppendChild(elem);
                        if (p.m_parent is Form)
                        {
                            FormWindowState windowState = ((Form)p.m_parent).WindowState;
                            xmlDoc.DocumentElement.SetAttribute("WindowState",((int)windowState).ToString());
                            //key.SetValue("WindowState", (int)windowState);
                        }                        
                        SaveControlLocation(xmlDoc, p, FileName);
                    }
                    ListView lv = p.m_parent as ListView;
                    string regpath_headers = regpath + @"\ColumnHeaders";
                    string FileName2 = di.FullName + regpath_headers.TrimEnd('\\') + @"\data.xml";
                    if (p.RestoreColumnsWidth == true && lv != null)
                    {
                        System.IO.DirectoryInfo di3 = new System.IO.DirectoryInfo(System.IO.Path.GetDirectoryName(FileName2));
                        if (di3.Exists == false) { di3.Create(); }

                        XmlDocument xmlDoc = new XmlDocument();
                        XmlElement elem = xmlDoc.CreateElement("data");
                        xmlDoc.AppendChild(elem);
                        // save ColumnHeaders                        
                        foreach (ColumnHeader ch in lv.Columns)
                        {
                            xmlDoc.DocumentElement.SetAttribute("col_" + lv.Columns.IndexOf(ch).ToString(), ch.Width.ToString());                            
                        }
                        xmlDoc.Save(FileName2);
                    }
                }
            }
            else
            {
                foreach (DictionaryEntry property in m_properties)
                {
                    Properties p = (Properties)property.Value;
                    string regpath = m_RegPath + m_subRegPath + p.m_subRegPath;
                    RegistryKey key = Registry.CurrentUser.CreateSubKey(regpath);
                    if (p.RestoreLocation == true) // Save only if RestoreLocation is True
                    {
                        if (p.m_parent is Form)
                        {
                            FormWindowState windowState = ((Form)p.m_parent).WindowState;
                            key.SetValue("WindowState", (int)windowState);
                        }
                        SaveControlLocation(key, p);
                    }
                    ListView lv = p.m_parent as ListView;
                    string regpath_headers = regpath + @"\ColumnHeaders";
                    if (p.RestoreColumnsWidth == true && lv != null)
                    {
                        // save ColumnHeaders
                        RegistryKey key_headers = Registry.CurrentUser.CreateSubKey(regpath_headers);
                        foreach (ColumnHeader ch in lv.Columns)
                        {
                            key_headers.SetValue(lv.Columns.IndexOf(ch).ToString(), ch.Width);
                        }
                    }
                }
            }
        }

		private void OnClosed(object sender, EventArgs e)
		{
            SaveProperties();
		}

        private void SaveControlLocation(XmlDocument xmlDoc, Properties p, string fileName)
        {
            if (p.m_wasMoved) // save Position
            {
                xmlDoc.DocumentElement.SetAttribute("Left", (p.m_normalLeft).ToString());
                xmlDoc.DocumentElement.SetAttribute("Top", (p.m_normalTop).ToString());                
            }
            if (p.m_wasResized) // save Size
            {
                xmlDoc.DocumentElement.SetAttribute("Width", (p.m_normalWidth).ToString());
                xmlDoc.DocumentElement.SetAttribute("Height", (p.m_normalHeight).ToString());
            }

            xmlDoc.Save(fileName);
        }

		private void SaveControlLocation(RegistryKey key, Properties p)
		{
			if(p.m_wasMoved) // save Position
			{
				key.SetValue("Left",p.m_normalLeft);
				key.SetValue("Top", p.m_normalTop);
			}
			if(p.m_wasResized) // save Size
			{
				key.SetValue("Width", p.m_normalWidth);
				key.SetValue("Height", p.m_normalHeight);
			}
		}

        
        private void OnLoad(object sender, System.EventArgs e)
		{
			// attach OnClosed event handler
			// Find the parent Form 
			Control parent = m_parent;
			m_subRegPath = @"\";
			while(!(parent is Form) && parent != null)
			{
				m_subRegPath = @"\" + parent.Name + m_subRegPath;
				parent = parent.Parent;
			} 
			m_parentForm = parent as Form;
			// add handlers if we have found a parent Form
			if(m_parentForm != null)
			{
				m_parentForm.Closed += new EventHandler(OnClosed);
			}
			else
			{
				// do not restore position if no parent form is found
				return;
			}

			// restore state/position
            LoadProperties();
		}

		/// <summary>
		/// Loads widths of the ListView columns from the registry
		/// </summary>
		/// <param name="key">Registry key where the widths of the ListView columns are stored</param>
		/// <param name="p">Instance of Properties class which a valid reference to ListView being restored</param>
		private void LoadListViewColumns(RegistryKey key, Properties p)
		{
			ListView lv = p.m_parent as ListView;
			if(lv != null && key != null)
			{
				foreach(ColumnHeader ch in lv.Columns)
				{
					object width = key.GetValue(lv.Columns.IndexOf(ch).ToString());
					if(width != null) ch.Width = (int)width;
				}
			}
		}

        /// <summary>
        /// Loads widths of the ListView columns from the registry
        /// </summary>
        /// <param name="key">Registry key where the widths of the ListView columns are stored</param>
        /// <param name="p">Instance of Properties class which a valid reference to ListView being restored</param>
        private void LoadListViewColumns(XmlDocument xmlDoc, Properties p)
        {
            if (xmlDoc.DocumentElement == null)
                return;

            ListView lv = p.m_parent as ListView;
            if (lv != null && xmlDoc != null)
            {
                foreach (ColumnHeader ch in lv.Columns)
                {
                    string width = xmlDoc.DocumentElement.GetAttribute("col_" + lv.Columns.IndexOf(ch).ToString());
                    if (width != null) ch.Width = int.Parse(width);
                }
            }
        }

		/// <summary>
		/// Loads size/position from the registry and sets Control.Location and Control.Size
		/// </summary>
		/// <param name="key">Registry key where the size/position of the control is stored</param>
		/// <param name="p">Instance of Properties class which a valid reference to control being restored</param>
		private void LoadControlLocationAndState(RegistryKey key, Properties p)
		{
			object left = key.GetValue("Left");
			object top = key.GetValue("Top");
			object width = key.GetValue("Width");
			object height = key.GetValue("Height");
			object windowState = key.GetValue("WindowState");

			// restore location
			if(left != null && top != null) 
			{
				Point location = new Point((int)left,(int)top);
				// Verify that the location falls inside one of the available screens,
				// otherwise don't restore it
				foreach (Screen screen in Screen.AllScreens)
				{
					if (screen.Bounds.Contains(location))
					{
						p.m_parent.Location = location;
						break;
					}
				}
			}

			// restore size
			if(width != null && height != null) 
			{
				p.m_parent.Size = new Size((int)width,(int)height);
			}

			// restore window state for the Form
			Form f = p.m_parent as Form;
			if(f != null && windowState != null)
			{
				f.WindowState = (FormWindowState)windowState;
				// do not allow minimized restore
				if(f.WindowState == FormWindowState.Minimized)
					f.WindowState = FormWindowState.Normal;
			}
		}

        /// <summary>
        /// Loads size/position from the registry and sets Control.Location and Control.Size
        /// </summary>
        /// <param name="key">Registry key where the size/position of the control is stored</param>
        /// <param name="p">Instance of Properties class which a valid reference to control being restored</param>
        private void LoadControlLocationAndState(XmlDocument xmlDoc, Properties p)
        {
            if (xmlDoc.DocumentElement == null)
                return;

            string left = xmlDoc.DocumentElement.GetAttribute("Left");
            string top = xmlDoc.DocumentElement.GetAttribute("Top");
            string width = xmlDoc.DocumentElement.GetAttribute("Width");
            string height = xmlDoc.DocumentElement.GetAttribute("Height");
            object windowState = null;
            if (!string.IsNullOrEmpty(xmlDoc.DocumentElement.GetAttribute("WindowState")))
                windowState = (FormWindowState)int.Parse(xmlDoc.DocumentElement.GetAttribute("WindowState"));
                
            // restore location
            if (!string.IsNullOrEmpty(left) && !string.IsNullOrEmpty(top))
            {
                Point location = new Point(int.Parse(left), int.Parse(top));
                // Verify that the location falls inside one of the available screens,
                // otherwise don't restore it
                foreach (Screen screen in Screen.AllScreens)
                {
                    if (screen.Bounds.Contains(location))
                    {
                        p.m_parent.Location = location;
                        break;
                    }
                }
            }

            // restore size
            if (!string.IsNullOrEmpty(width) && !string.IsNullOrEmpty(height))
            {
                p.m_parent.Size = new Size(int.Parse(width), int.Parse(height));
            }

            // restore window state for the Form
            Form f = p.m_parent as Form;
            if (f != null && windowState != null)
            {
                f.WindowState = (FormWindowState)windowState;
                // do not allow minimized restore
                if (f.WindowState == FormWindowState.Minimized)
                    f.WindowState = FormWindowState.Normal;
            }
        }
		#endregion

		bool IExtenderProvider.CanExtend(object o)
		{
			if(o is Control)
				return true;
			else
				return false;
		}

		/// <summary>
		/// Main purpose: represent Control's location 
		/// Additional purpose: store values of extended properties
		/// note: extended properties are: RestoreLocation and RestoreColumnsWidth
		/// </summary>
		public class Properties
		{
			public bool RestoreLocation;	// "Extended" property
			public bool RestoreColumnsWidth;// "Extended" property

			// variables to save to Registry
			public int m_normalLeft;
			public int m_normalTop;
			public int m_normalWidth;
			public int m_normalHeight;

			// helper variables
			public bool m_wasResized = false;
			public bool m_wasMoved = false;
			private bool m_isForm;

			public Control m_parent;
			public string m_subRegPath;

			public Properties(object o)
			{
				RestoreLocation = (o is Form); // default true for Form
				RestoreColumnsWidth = false;	// default is false
				m_parent = (Control)o;		// type cast should not result to null
				m_isForm = (o is Form);
				// if o is Form then m_subRegPath is empty string
				m_subRegPath = (o is Form) ? String.Empty : m_parent.Name;
				
				// attach to Resize and Move
				m_parent.Resize += new System.EventHandler(OnResize);
				m_parent.Move += new System.EventHandler(OnMove);
			}
			#region Event Handlers
			private void OnResize(object sender, System.EventArgs e)
			{
				// when the control is resized we will save the new size 
				// in m_normalWidth and m_normalheight variables
				// unless the control is a Form, which is currently Maximized or Minimized
				if(!m_isForm || ((Form)m_parent).WindowState == FormWindowState.Normal)
				{
					m_wasResized = true;
					m_normalWidth = m_parent.Width;
					m_normalHeight = m_parent.Height;
				}
			}

			private void OnMove(object sender, System.EventArgs e)
			{
				// when the control is moved we will save the new position 
				// in m_normalLeft and m_normalTop variables
				// unless the control is a Form, which is currently Maximized or Minimized
				if(!m_isForm || ((Form)m_parent).WindowState == FormWindowState.Normal)
				{
					m_wasMoved = true;
					m_normalLeft = m_parent.Left;
					m_normalTop = m_parent.Top;
				}
			}

		#endregion
		}
	
		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
		}
		#endregion
	}

	/// <summary>
	///   Designer object used to set the Parent property. 
	/// </summary>
	internal class RealPositionDesigner : ComponentDesigner 
	{
		///   <summary>
		///   Sets the Parent property to "this" - 
		///   the Form/UserControl where the component is being dropped. 
		///   </summary>
		public override void OnSetComponentDefaults()
		{
			RealPosition rp = (RealPosition)Component;
			rp.Parent = (Control)Component.Site.Container.Components[0];
		}
	}	
}


modified 24-Mar-16 9:36am.

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.