Hi,

I am building a library of composite controls in ASP.NET 2.0. My
controls consist of a regular ASP.NET control like a text box and a
bunch of validators.

I attach the source code for one of my composite controls to this post.
If you are interested in attempting something similar, feel free to use
my code.

If you have already done something like that, please take a look and
let me know if I am doing anything wrong. Also let me know how you
expose the internal controls? Do you expose the actual controls or just
properties that are mapped to the properties of the underlying
controls?

If you thought about doing something similar, but decided to go some
other way, could you tell me why decided not to go this route?


using System;
using System.ComponentModel;
using System.Data;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MyNamespace.Data;
using MyNamespace.Web.UI.Validators;

namespace MyNamespace.Web.UI.WebControls
{
[AspNetHostingPermission(SecurityAction.Demand, Level =
AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.Inheritance Demand, Level =
AspNetHostingPermissionLevel.Minimal)]
[ToolboxData("<{0}:textbox required=\"false\" runat=\"server\"
/>")]
[ValidationProperty("Text")]
public class TextBox : CompositeControl
{
protected System.Web.UI.WebControls.TextBox _textBox = null;
protected RequiredFieldValidator _reqValidator = null;
protected RegularExpressionValidator _regExValidator = null;
protected TextBoxLengthValidator _lengthValidator = null;
protected string _regExValidatorErrorMessage = string.Empty;

#region Constructors

public TextBox()
{
EnsureChildControls();
}

#endregion

#region Error Messages

public const string REQUIRED = "is a required field.";
public const string REGEX = "is invalid.";
public const string LENGTH = "length has to be {0} to {1}
characters long";

#endregion

#region Public Properties

public System.Web.UI.WebControls.TextBox InnerTextBox
{
get { return _textBox; }
}

public RequiredFieldValidator InnerRequiredFieldValidator
{
get { return _reqValidator; }
}

public RegularExpressionValidator
InnerRegularExpressionValidator
{
get { return _regExValidator; }
}

public TextBoxLengthValidator InnerTextBoxLengthValidator
{
get { return _lengthValidator; }
}

public TextBoxMode TextMode
{
get { return _textBox.TextMode; }
set { _textBox.TextMode = value; }
}

public bool ReadOnly
{
get
{
object o = ViewState["ReadOnly"];
if (o == null)
{
return false;
}
else
{
return bool.P(o.ToString());
}
}
set { ViewState["ReadOnly"] = value; }
}

public int MaxLength
{
get { return _lengthValidator.MaximumLength; }
set
{
_lengthValidator.MaximumLength = value;
SetupValidators();
}
}

public int MinLength
{
get { return _lengthValidator.MinimumLength; }
set
{
_lengthValidator.MinimumLength = value;
SetupValidators();
}
}

public string RegularExpression
{
get { return _regExValidator.ValidationExpression; }
set
{
_regExValidator.ValidationExpression = value;
SetupValidators();
}
}

public string DisplayName
{
get
{
object o = ViewState["DisplayName"];
if (o == null)
{
return string.Empty;
}
else
{
return o.ToString();
}
}
set
{
ViewState["DisplayName"] = value;
SetupValidators();
}
}

public bool Required
{
get { return _reqValidator.Visible; }
set
{
_reqValidator.Visible = value;
SetupValidators();
}
}

public virtual string Text
{
get { return _textBox.Text; }
set { _textBox.Text = value; }
}

#endregion

protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit(e);
}

protected override void Render(HtmlTextWriter writer)
{
_textBox.Width = Width;
_textBox.Height = Height;
_textBox.RenderControl(writer);

_reqValidator.RenderControl(writer);
_lengthValidator.RenderControl(writer);
_regExValidator.RenderControl(writer);
}

protected override void CreateChildControls()
{
Controls.Clear();

_textBox = new System.Web.UI.WebControls.TextBox();
_textBox.ID = "textBox";
Controls.Add(_textBox);

//Add required validator
_reqValidator = new RequiredFieldValidator();
Controls.Add(_reqValidator);

//Add length validator
_lengthValidator = new TextBoxLengthValidator();
Controls.Add(_lengthValidator);

//Add RegularExpression validator
_regExValidator = new RegularExpressionValidator();
Controls.Add(_regExValidator);

if (Width.Value == 0)
{
_textBox.Width = Unit.Pixel(170);
}

Required = false;

SetupValidators();
}

private void SetupValidators()
{
_reqValidator.Display = ValidatorDisplay.None;
_reqValidator.ControlToValidate = _textBox.ID;

_lengthValidator.Display = ValidatorDisplay.None;
_lengthValidator.ControlToValidate = _textBox.ID;

_regExValidator.Display = ValidatorDisplay.None;
_regExValidator.ControlToValidate = _textBox.ID;


if (MaxLength > 0)
{
_textBox.MaxLength = MaxLength;
}

_lengthValidator.Visible = (MaxLength > 0 || MinLength >
0);

_regExValidator.Visible = RegularExpression.Length > 0;

//
_reqValidator.ErrorMessage = DisplayName + " " + REQUIRED;

//
if (MinLength == 0 && MaxLength > 0)
{
_lengthValidator.ErrorMessage = DisplayName + " "
+ string.Format("is too
long. {0} characters max.", MaxLength);
}
else if (MinLength > 0 && MaxLength == 0)
{
_lengthValidator.ErrorMessage = DisplayName + " "
+ string.Format("is too
short. {0} characters min.", MinLength);
}
else if (MinLength > 0 && MaxLength > 0)
{
_lengthValidator.ErrorMessage = DisplayName + " "
+
string.Format("has to
be {0} to {1} characters long.", MinLength,

MaxLength);
}
else if (MinLength > 0 && MaxLength > 0 && MinLength ==
MaxLength)
{
_lengthValidator.ErrorMessage = DisplayName + " "
+ string.Format("has to
be {0} characters long.", MinLength);
}

_regExValidator.ErrorMessage = DisplayName + " " + REGEX;
}
}
}