HomeASP.NET Developing a Wonderful ASP.NET TextField C...
Developing a Wonderful ASP.NET TextField Control
This article introduces you to the concept of the User Control. It also walks you through the development of a well-featured TextField control with several functionalities.
The entire solution (source code) for this article is available as a free download in the form of a zip, as shown above. The source code in this article has been developed using Microsoft Visual Studio 2005 Professional Edition on Microsoft Windows Server 2003 Standard Edition. I didn't really test any of the code in any other tools/IDEs/servers/editions/versions. If you have any problems, please feel free to post in the discussion area.
Introduction
ASP.NET contains a control framework that is used by developers to create different user interfaces for their web applications. This framework is often referred to as web forms. The controls related to web forms are generally termed server controls.
The server control architecture is extensible; component developers design and implement new server controls. These new server controls are categorized into "User Controls" and "Custom Controls." Any of these controls are generally the extensions of existing server controls or extensions to the "Control" base class. Each of these controls gets converted to HTML tags at run time. This hides all the complexities and inconsistencies of any browser used for browsing the web application.
Several of these controls are made up of different properties, methods and events. These controls may also use "View State" to manage the state of server controls across individual web requests. Managing the state can be understood as "remembering the values or choices of the user across multiple requests of several pages."
Coming to the difference between a "User Control" and a "Custom Control," a "User Control" simply behaves like an include file with an ASCX extension. User controls are little more than a snippet of a web page that can be dragged and dropped onto the same web page for any number of times. They can be easily reused across any number of pages.
A "Custom Control" is a compiled code component and a lot more than a user control. A custom control is more complex to create when compared to a user control. When developing a custom control, you take hold of the control completely for both design time and run time execution. It gives you WYSISWYG features along with design time customization. You may have to emit lot of HTML and JavaScript depending upon the flavors of the features you require.
In this section, I would like to introduce a new textbox control called "uctTextField." The "uct" stands for "User Control" as part of my naming convention. Let us consider the features not available with the existing Textbox server control (which is available as part of the ASP.NET framework).
It doesn't support labeling. You may have to add another label control to support the existing Textbox control.
To maintain some gap between Label and Textbox, you may have to work with TABLEs in HTML.
It doesn't have the "required input" option. You may have to add RequiredFieldValidator to the same Textbox control separately.
It doesn't have support for hints. Hints (or messages of format, etc.) are generally used when inputting dates and other items. You may have to add another Label control to support the same.
If I disable the Textbox, it simply locks the user out of the Textbox. But it doesn't automatically convert to Label (when in disabled mode).
At the moment, I feel that these features are frequently used in every application. Now imagine what would happen if I have five textboxes on the web page. I have to create five labels, validators, hint labels, and read-only labels, working with layout and more. You may want to be able to implement your own features instead of (or in addition to) the ones I've described here. This scenario is always boring for any ASP.NET developer.
To solve these "boring" problems, to a certain extent (or even to the full extent sometimes), user controls would be a great help. Now, I would like to design and develop a user control (called "uctTextField") supporting all of the above features. Once the control is developed, it can be dragged and dropped onto the web page any number of times, and it really improves my productivity.
Developing your own flexible Textbox control with new features: the beginning
Once you know the requirements for creating a new user control, it is time to implement the user control as part of your ASP.NET web solution. Using the Solution Explorer, right click on your solution and choose Add New Item. Within the Add New Item dialog box, select Web User Control as the template, provide the name of the User Control as "uctTextField" and hit Add.
Drag and drop the controls (and other stuff) onto your user control, so that it looks likes the following in the source mode:
According to the above source, you can understand that the entire control is a part of the Panel control. Within the panel, I created a simple HTML table to lay out all the controls in a convenient manner. The control mainly contains three Label controls, one Textbox control and one RequiredFieldValidator. For my convenience in layout, I added two more panels within the HTML table. The layout should look like the following in design mode (Fig 01).
I removed the code for clarity. Based on the discussion of the requirements in previous sections, I came up with the above list of properties, methods and events. You can modify the properties according to your naming conventions and standards. My intention is just to give you an idea of the list of features of the user control.
Developing your own flexible Textbox control with new features: coding events
I am currently using Page Events to simply maintain ViewState. The code is as follows:
#Region"Page Events"
ProtectedSub Page_Load(ByVal sender AsObject, ByVal e As System.EventArgs) HandlesMe.Load If IsPostBack Then Me.ErrorText = ViewState("ErrorText") Required = ViewState("Required") EndIf EndSub
ProtectedSub Page_PreRender(ByVal sender AsObject, ByVal e As System.EventArgs) HandlesMe.PreRender ViewState("ErrorText") = ErrorText ViewState("Required") = Required EndSub
#EndRegion
The only method I used is the Focus method. When the control receives the focus, the cursor should be available in the text box. If the control is in read-only mode, it will not be able to receive any focus. It is defined as follows:
PublicOverridesSub Focus() If Editable Then txtControl.Focus() EndSub
Our control should also be supporting TextChanged event, and I created it as follows:
#Region"Events" PublicEvent TextChanged As EventHandler ProtectedSub txtControl_TextChanged(ByVal sender AsObject, ByVal e As System.EventArgs) Handles txtControl.TextChanged Me.Text = txtControl.Text RaiseEvent TextChanged(sender, e) EndSub #EndRegion
The coding for the properties is very simple and easy to understand. The following is the entire code for all the properties mentioned in the skeleton:
<EditorBrowsable(EditorBrowsableState.Always), _ DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), _ Bindable(True), Browsable(True), Category("Common")> _ PublicProperty Text() AsString Get ReturnMe.txtControl.Text EndGet Set(ByVal Value AsString) Me.txtControl.Text = Value Me.lblControl.Text = Value EndSet EndProperty
<Category("Common")> _ PublicProperty MaxLength() AsInteger Get ReturnMe.txtControl.MaxLength EndGet Set(ByVal value AsInteger) Me.txtControl.Columns = value Me.txtControl.MaxLength = value EndSet EndProperty
<Category("Common")> _ PublicProperty ErrorText() AsString Get Return m_strErrorText EndGet Set(ByVal Value AsString) Me.reqfValidator.ErrorMessage = Value & " is required." m_strErrorText = Value EndSet EndProperty
<Category("Common")> _ PublicProperty Editable() AsBoolean Get ReturnMe.txtControl.Visible EndGet Set(ByVal Value AsBoolean) If Editable <> Value Then If Editable Then lblControl.Text = Me.txtControl.Text EndIf lblControl.Visible = Not Value txtControl.Visible = Value reqfValidator.Enabled = Value And Required spnRequiredIndicator.Visible = Value And Required EndIf EndSet EndProperty
<Category("Common")> _ PublicProperty Required() AsBoolean Get Return m_blnRequired EndGet Set(ByVal Value AsBoolean) reqfValidator.Enabled = Editable And Value spnRequiredIndicator.Visible = Editable And Value m_blnRequired = Value EndSet EndProperty
<Category("Field Text")> _ PublicProperty LabelTextValue() AsString Get ReturnMe.lblText.Text EndGet Set(ByVal value AsString) Me.lblText.Text = value EndSet EndProperty
<Category("Field Text")> _ PublicProperty LabelTextAlign() As System.Web.UI.WebControls.HorizontalAlign Get Return pnlText.HorizontalAlign EndGet Set(ByVal Value As System.Web.UI.WebControls.HorizontalAlign) pnlText.HorizontalAlign = Value EndSet EndProperty
<Category("Field Text")> _ PublicProperty LabelTextVisible() AsBoolean Get ReturnMe.pnlText.Visible EndGet Set(ByVal Value AsBoolean) Me.pnlText.Visible = Value EndSet EndProperty
<Category("Field Text")> _ PublicProperty LabelTextWidth() As System.Web.UI.WebControls.Unit| Get Return pnlText.Width EndGet Set(ByVal Value As System.Web.UI.WebControls.Unit) pnlText.Width = Value EndSet EndProperty
Developing your own flexible Textbox control with new features: coding properties continued
The following is the continuation of the previous section for the entire code for all of the properties mentioned in the skeleton:
PublicProperty AutoPostBack() AsBoolean Get Return txtControl.AutoPostBack() EndGet Set(ByVal Value AsBoolean) txtControl.AutoPostBack = Value EndSet EndProperty
<Category("Appearance")> _ PublicProperty CssClassTextBoxControl() AsString Get Return txtControl.CssClass EndGet Set(ByVal Value AsString) txtControl.CssClass = Value EndSet EndProperty
<Category("Appearance")> _ PublicProperty CssClassLabelControl() AsString Get ReturnMe.lblControl.CssClass EndGet Set(ByVal value AsString) Me.lblControl.CssClass = value EndSet EndProperty
<Category("Appearance")> _ PublicProperty CssClassLabelText() AsString Get ReturnMe.lblText.CssClass EndGet Set(ByVal value AsString) Me.lblText.CssClass = value EndSet EndProperty
<Category("Appearance")> _ PublicProperty Tooltip() AsString Get Return pnlControl.ToolTip EndGet Set(ByVal Value AsString) pnlControl.ToolTip = Value EndSet EndProperty
PublicProperty ValidationGroup() AsString Get ReturnMe.txtControl.ValidationGroup EndGet Set(ByVal value AsString) Me.txtControl.ValidationGroup = value Me.reqfValidator.ValidationGroup = value EndSet EndProperty
PublicProperty HintMessage() AsString Get ReturnMe.lblHint.Text EndGet Set(ByVal value AsString) Me.lblHint.Text = value EndSet EndProperty
PublicProperty HintMessageVisible() AsBoolean Get ReturnMe.pnlHint.Visible EndGet Set(ByVal value AsBoolean) Me.pnlHint.Visible = value EndSet EndProperty
I hope you enjoyed this article. Any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com