Introduction
If you have worked on VB6 based thick client applications, one common problem you as a developer would have encountered is the way controls work. There were a handful of issues in terms of customization of controls. .Net answers them through use of customizing existing controls using Inherited controls or creating a new control by inheriting User Control. This article uses Windows Form's TextBox control to explain how to design your controls.
There is difference between Inherited Controls and User Controls in practical implementation even though conceptually both can be grouped under Custom Controls category. Inherited controls are those existing controls that user would inherit to add custom functionalities. E.g. TextBox, DataGrid; Usually these are used for common validations, GUI features etc. User Controls are controls that user creates using either one or more controls, add some common application logic. This inherits "System.Windows.Forms.UserControl"; so one can add a Combo Box, DataGrid, ImageList etc. Make the modifiers public, protected; add some common application logic like on selection of Combo value the DataGrid is revalidated.
Why?
Consider a very simple scenario in Windows Forms. I want to validate a user's entry to a TexBox control i.e either numeric, text, URL etc. One way to do that would be just add keypress event of textbox as follows:
public
class frmTestControls : System.Windows.Forms.Form{
private System.Windows.Forms.TextBox txtLogin;
private System.ComponentModel.IContainer components;
public frmTestControls()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.txtLogin = new System.Windows.Forms.TextBox();
this.KeyPress += new KeyPressEventHandler(OnKeyPress);
this.SuspendLayout();
//Some more code goes here …
}
private void OnKeyPress(object sender,KeyPressEventArgs e)
{
//Some code goes here …
}
}
Let us consider that you did the above for a textbox control that should allow only numerical entries and had a specific format "0.00". This was implemented throughout the application that had around 30-40 user input boxes of type numeric. One fine day you want the numeric format to be "0.000". Now to get this small change done we may have to once again do a code change through out the application. Many might argue that I would use application config files to get these values. I agree, but consider a situation that had events like MouseDown, Leave, Enter, LostFocus etc that may have been used for each of these textboxes for whatever GUI features or common validations as applicable. A better approach to do this would be to use the Inherited Controls judiciously.
Sample Implementation
Objective: Design for common TextBox control for the application to manage changes with ease.
Step 1:
This textbox should be flexible to validate for all type of user entries. First design your constructors for controls. In this case nothing much to do in terms of overloading, hence we go with the default constructor. Create an Enum for validation types to implement the same. I use Enum because today I have only Numeric and Text as the types but in future I could add URL, Social Security Number, some specifc patterns to identify inventory bins like '000-XXX' etc. Then decide on Events based on the type of features and validations that the textbox must provide. In the example I have selected the Leave and Enter events to add some UI features. KeyPress and LostFocus is an event that I require for validating most events.
namespace Orbit-e.Controls
{
public enum ValidationType
{
Text=0,
Numeric,
URL,
SSN,
InventoryBin_Pattern
}
public class in4CommonTextBox : System.Windows.Forms.TextBox
{
public in4CommonTextBox():base()
{
InitializeComponent();
this.AutoSize =false;
this.Width =160;
this.Height =20;
this.ForeColor = Color.Blue;
this.BackColor = Color.White;
this.BorderStyle = BorderStyle.Fixed3D;
//Set for all the events and write the corresponding events
this.KeyPress += new KeyPressEventHandler(OnKeyPress);
this.Leave +=new EventHandler(onLeave);
this.Enter +=new EventHandler(onEntering);
this.MouseDown += new MouseEventHandler(onMouseDown);
this.LostFocus +=new EventHandler(OnLostFocus);
}
}
}
Step 2:
Decide on how to handle the GUI features like Height, Width, color and style. If personalization features like themes are to be provided then usually one way to do this is to create a user configuration file for storing theme schemes that include BackColor, ForeColor. A common technique to figure out the default color schemes would help for designing other controls as well. The height and Width are very important aspects since this helps maintain uniformity in the UI looks. Also add accessor to set the type of validation and make sure that there is always a default value assigned.
private
int intValidType=(int) ValidationType.Textpublic ValidationType ValidateFor
{
set
{
intValidType = (int) value;
}
}
Step 3:
Join the conversation! Your thoughts help the community grow.