CompositeControl or WebControl

11 בפברואר 2008

3 תגובות

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!

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

3 תגובות

  1. Softwaretechnik23 במרץ 2008 ב 2:25

    well done!

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

    … regards from germany

    להגיב
  2. Dejan7 בדצמבר 2008 ב 16:27

    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

    להגיב
  3. Gilad Lavian12 בדצמבר 2008 ב 13:03

    Dejan, many thanks for the kind words.
    And thanks for notice my grammer mistake, i've fixed that.

    להגיב