Click here to Skip to main content
15,881,204 members
Articles / Programming Languages / C#

Coding in Tiers - Part I

Rate me:
Please Sign up or sign in to vote.
4.29/5 (24 votes)
14 Sep 20035 min read 70K   2.7K   86  
Automate UI Form population
using System;
using System.Reflection;
using System.Windows.Forms;

namespace Auto
{
	#region -- Automator --
	/// <summary>
	/// A utility class for auto populating windows forms.
	/// </summary>
	public sealed class Automator
	{
		#region -- Constructors --
		/// <summary>
		/// Create a new mediator for the specified form.
		/// </summary>
		/// <param name="winForm">The windows Form object</param>
		public Automator(Form winForm)
			:this(winForm, null)
		{
		}

		/// <summary>
		/// Create a new mediator for the specified form to store the
		/// object state.
		/// </summary>
		/// <param name="winForm">The windows Form object</param>
		/// <param name="state">The current state of the form</param>
		public Automator(Form winForm, object state)
		{
			this.winForm = winForm;
			this.state = state;
		}
		#endregion

		#region -- Properties --
		private object state;
		/// <summary>
		/// The current state of the object
		/// </summary>
		public object State
		{
			get
			{
				return this.state;
			}
			set
			{
				this.state = value;
			}
		}

		private Form winForm;
		/// <summary>
		/// The windows Form
		/// </summary>
		public Form WinForm
		{
			get
			{
				return this.winForm;
			}
		}
		#endregion

		#region -- Methods --
		/// <summary>
		/// Store the current state of the form
		/// </summary>
		public void Store()
		{
			Store(this.WinForm);
		}

		/// <summary>
		/// Restore the form to it's last state
		/// </summary>
		public void Restore()
		{
			Restore(this.WinForm);
		}
		
		/// <summary>
		/// Store the state of the control using the property on the
		/// State object by matching the name of the control with the
		/// name of the property. Type conversions will be performed
		/// on the value if necessary.
		/// </summary>
		/// <param name="control">The control whose state is to be stored</param>
		private void Store(Control control)
		{
			// Obtain the type of the State object
			Type type = this.State.GetType();

			// Check if the control has a valid name
			if(control.Name != null)
			{
				// Obtain the property whose name matches the control name
				PropertyInfo info = type.GetProperty(control.Name);

				// Does such a property exist?
				if(info != null)
				{
					// Set the property value corresponding to the value on the control
					info.SetValue(state, GetValue(info.PropertyType, control), null);
				}

				// Check if the control itself contains any nested controls
				Control.ControlCollection ctrls = control.Controls;

				// Iterate over the controls in the collection
				foreach (Control ctrl in ctrls)
				{
					// Store the state of the control
					Store(ctrl);
				}
			}
		}

		/// <summary>
		/// Restore the state of the control using the property on the
		/// State object by matching the name of the control with the
		/// name of the property.
		/// </summary>
		/// <param name="control">The control whose state is to be restored</param>
		private void Restore(Control control)
		{
			// Obtain the type of the State object
			Type type = this.State.GetType();

			// Check if the control has a valid name
			if(control.Name != null)
			{
				// Obtain the property whose name matches the control name
				PropertyInfo info = type.GetProperty(control.Name);

				if(info != null)
				{
					// Set the control value corresponding to the value on the property
					SetValue(control, info.GetValue(state, null));
				}

				// Check if the control itself contains any nested controls
				Control.ControlCollection ctrls = control.Controls;

				// Iterate over the controls in the collection
				foreach (Control ctrl in ctrls)
				{
					// Restore the state of the control
					Restore(ctrl);
				}
			}
		}

		/// <summary>
		/// Obtain the value object from the control
		/// </summary>
		/// <param name="type">The property type</param>
		/// <param name="control">The control from which the value has to be extracted</param>
		/// <returns>The value to be set</returns>
		private object GetValue(Type type, object control)
		{
			object src = null;

			switch(control.GetType().ToString())
			{
				case "System.Windows.Forms.TextBox":
					// Text from a text box
					src = ((TextBox)control).Text;
					break;
				case "System.Windows.Forms.ComboBox":
					// SelectedItem of a combo box
					src = ((ComboBox)control).SelectedItem;
					break;
				case "System.Windows.Forms.ListBox":
					// Single or Multiple values of a list box depending on SelectionMode
					ListBox list = (ListBox)control;

					// Check the list selection mode
					if(list.SelectionMode != SelectionMode.MultiSimple &&
						list.SelectionMode != SelectionMode.MultiExtended)
					{
						// Obtain the selected item
						src = list.SelectedItem;
					}
					else
					{
						// Obtain all the selected items
						ListBox.SelectedObjectCollection soc = list.SelectedItems;

						// Copy the selected values in an array
						string[] array = new string[soc.Count];
						soc.CopyTo(array, 0);

						// Set the values
						src = array;
					}
					break;
				case "System.Windows.Forms.CheckBox":
					// Checked state of a check box
					src = ((CheckBox)control).Checked;
					break;
				case "System.Windows.Forms.RadioButton":
					// Checked state of a radio button
					src = ((RadioButton)control).Checked;
					break;
				default:
					break;
			}

			// Perform any type conversions if necessary
			return ConvertValue(type, src);
		}

		/// <summary>
		/// Set the value on the control
		/// </summary>
		/// <param name="control">The control on which the value has to be set</param>
		/// <param name="obj">The value to be set</param>
		private void SetValue(object control, object obj)
		{
			// Obtain the type of control
			switch(control.GetType().ToString())
			{
				case "System.Windows.Forms.TextBox":
					// Text from a text box
					((TextBox)control).Text = Convert.ToString(obj);
					break;
				case "System.Windows.Forms.ComboBox":
					// SelectedItem of a combo box
					((ComboBox)control).SelectedItem = obj;
					break;
				case "System.Windows.Forms.ListBox":
					// Single or Multiple values of a list box depending on SelectionMode
					ListBox list = (ListBox) control;

					// Check the list selection mode
					if(list.SelectionMode != SelectionMode.MultiSimple &&
						list.SelectionMode != SelectionMode.MultiExtended)
					{
						// Set the selected item
						list.SelectedItem = obj;
					}
					else
					{
						// Iterate over the array
						foreach(object selected in (obj as object[]))
						{
							// Select the index of the list corresponding to the
							// value in the array
							list.SetSelected(list.Items.IndexOf(selected), true);
						}
					}
					break;
				case "System.Windows.Forms.CheckBox":
					// Checked state of a check box
					((CheckBox)control).Checked = Convert.ToBoolean(obj);
					break;
				case "System.Windows.Forms.RadioButton":
					// Checked state of a radio button
					((RadioButton)control).Checked = Convert.ToBoolean(obj);
					break;
				default:
					break;
			}
		}

		/// <summary>
		/// Perform type conversions if necessary
		/// </summary>
		/// <param name="type">The type to be compared</param>
		/// <param name="src">The source value</param>
		/// <returns>The value to be set</returns>
		private object ConvertValue(Type type, object src)
		{
			// Target value
			object dest = null;

			if(src != null)
			{
				// Pretty self explanatory!
				if(type == typeof(String))
				{
					dest = src;
				}
				else if(type == typeof(Boolean))
				{
					dest = Convert.ToBoolean(src);
				}
				else if(type == typeof(Byte))
				{
					dest = Convert.ToByte(src);
				}
				else if(type == typeof(Char))
				{
					dest = Convert.ToChar(src);
				}
				else if(type == typeof(DateTime))
				{
					dest = Convert.ToDateTime(src);
				}
				else if(type == typeof(Decimal))
				{
					dest = Convert.ToDecimal(src);
				}
				else if(type == typeof(Double))
				{
					dest = Convert.ToDouble(src);
				}
				else if(type == typeof(Int16))
				{
					dest = Convert.ToInt16(src);
				}
				else if(type == typeof(Int32))
				{
					dest = Convert.ToInt32(src);
				}
				else if(type == typeof(Int64))
				{
					dest = Convert.ToInt64(src);
				}
				else if(type == typeof(SByte))
				{
					dest = Convert.ToSByte(src);
				}
				else if(type == typeof(Single))
				{
					dest = Convert.ToSingle(src);
				}
				else if(type == typeof(UInt16))
				{
					dest = Convert.ToUInt16(src);
				}
				else if(type == typeof(UInt32))
				{
					dest = Convert.ToUInt32(src);
				}
				else if(type == typeof(UInt64))
				{
					dest = Convert.ToUInt64(src);
				}
				else
				{
					// Default if none match
					dest = src;
				}
			}

			// Return the value to be set
			return dest;
		}
		#endregion
	}
	#endregion
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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
Web Developer
United States United States
Over 15 years of experience in designing and architecting high availability/scalability financial application software using OO technologies such as C++/Java/C#.

Comments and Discussions