DCSIMG
CompositeControl or WebControl - Gilad Lavian's Blog

Gilad Lavian's Blog

In Development

CompositeControl or WebControl

Whenever possible, i rather to use UserControl instead of WebControl, since WebControls are more complicate to create and later on to maintain.

But in case that i have to build a WebControl, i rather build a CompositeControl.

Way CompositeControl?

CompositeControl eventually inherit from WebControl, but each control inside the CompositeControl manage its own life cycle events and the ViewState / PostBack data.

This means that we going to save a lots of code writing by not handling this events our self's.

Implementing the CompositeControl

Create the following code in a new Class Library:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace BaseType.Composite.Controls
{
    public class LoginControl : CompositeControl
    {
        /// <summary>
        /// Occurs when [login submit].
        /// </summary>
        public event EventHandler LoginSubmit;

        /// <summary>
        /// Gets or sets the name of the user.
        /// </summary>
        /// <value>The name of the user.</value>
        public string UserName
        {
            get { return ((TextBox)this.FindControl("UserName")).Text; }
            set { ((TextBox)this.FindControl("UserName")).Text = value; }
        }

        /// <summary>
        /// Gets or sets the password.
        /// </summary>
        /// <value>The password.</value>
        public string Password
        {
            get { return ((TextBox)this.FindControl("Password")).Text; }
            set { ((TextBox)this.FindControl("Password")).Text = value; }
        }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based 
        /// implementation to create any child controls they contain in preparation for posting back or 
        /// rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            TextBox tbUserName = new TextBox();
            TextBox tbPassword = new TextBox();

            tbUserName.ID = "UserName";
            tbPassword.ID = "Password";

            Button btLogin = new Button();
            btLogin.Text = "Login";
            btLogin.Click += new EventHandler(btLogin_Click);

            HtmlTable table = new HtmlTable();
            HtmlTableRow tr;
            HtmlTableCell td;

            //Add the UserName textbox
            tr = new HtmlTableRow();
            td = new HtmlTableCell();
            td.InnerHtml = "UserName:";
            tr.Controls.Add(td);

            td = new HtmlTableCell();
            td.Controls.Add(tbUserName);
            tr.Controls.Add(td);
            table.Controls.Add(tr);

            //Add the Password textbox
            tr = new HtmlTableRow();
            td = new HtmlTableCell();
            td.InnerHtml = "Password:";
            tr.Controls.Add(td);

            td = new HtmlTableCell();
            td.Controls.Add(tbPassword);
            tr.Controls.Add(td);
            table.Controls.Add(tr);

            //Add the Login button
            tr = new HtmlTableRow();
            td = new HtmlTableCell();
            td.InnerHtml = "&nbsp;";
            tr.Controls.Add(td);

            td = new HtmlTableCell();
            td.Controls.Add(btLogin);
            tr.Controls.Add(td);
            table.Controls.Add(tr);

            //Add the Table to this control
            this.Controls.Add(table);
        }

        /// <summary>
        /// Handles the Click event of the btLogin control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void btLogin_Click(object sender, EventArgs e)
        {
            if (LoginSubmit != null) LoginSubmit(this, e);
        }
    }
}

Once compiled, you can add the Control to your Toolbox by adding the .DLL file.

Using the LoginControl

After adding the control to your toolbox, all you need to do is to drag him to you designer:

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="Default.aspx.cs" Inherits="Test._Default" %>

<%@ Register Assembly="BaseType.CompositeControls" 
    Namespace="BaseType.Composite.Controls" TagPrefix="cc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <cc1:LoginControl ID="LoginControl1" runat="server" 
            OnLoginSubmit="LoginControl1_LoginSubmit" />
    </div>
    </form>
</body>
</html>

You can hook to the LoginSubmit event from designer:

RegiterLoginEvent

<cc1:LoginControl ID="LoginControl1" runat="server" 
    OnLoginSubmit="LoginControl1_LoginSubmit" />

After posting the form, you can get the UserName and Password for the LoginControl class already exposed properties, since CompositeControl already managing the ViewState and Postback data for us:

protected void LoginControl1_LoginSubmit(object sender, EventArgs e)
{
    Response.Write(LoginControl1.UserName);
}

The Control in action

Login

Enjoy!

תוכן התגובה

Softwaretechnik כתב/ה:

well done!

this is really good code and shows up the real power vs webcontrol...

... regards from germany

# March 23, 2008 2:25 AM

Web Development Community כתב/ה:

You are voted (great) - Trackback from Web Development Community

# December 7, 2008 8:34 AM

DotNetKicks.com כתב/ה:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# December 7, 2008 8:35 AM

Dejan כתב/ה:

Interesting article, recently I've been looking into best practices for control development myself and I wish I had seen this article before I read so many different sources to find out the same stuff that you summarized neatly here

Cheers

PS Don't want to sound like grammar police, but on few places you've written sense instead of since

# December 7, 2008 4:27 PM

Gilad Lavian כתב/ה:

Dejan, many thanks for the kind words.

And thanks for notice my grammer mistake, i've fixed that.

# December 12, 2008 1:03 PM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 2 and 2 and type the answer here:


Enter the numbers above: