Paul, you may try exposing a couple of templates. That is the alternative
route and you will get more flexibility in what you can do. Grouping your
controls within templates is much better. Just make sure that the validator
controls are grouped together with the fields they validate, either within
the same template or in different templates but within the same
NamingContainer.
You will also need to expose an itemcreated event with an argument that
gives you a handle on the template that contains the control or something
like that which you can use to retrieve the controls contained within your
templates. You wont be able to access them directly.
Another thing to be aware of is controls nested within your templates that
fire events, for these also you might want to override OnBubbleEvent in the
template and expose another generic method that fires for all click events
etc. You might have noticed this when using datacontrols like datalist,
repeater or datagrid controls, who expose ItemCreated and ItemCommand(for
events).
I wanted to include complete working code but it gets too involved and i'm
not sure this is the route you want to take anyway, but its a very common
topic and there are many examples by many bloggers or msdn itself.
Here is a simplistic example on msdn :
http://msdn2.microsoft.com/en-us/library/system.web.ui.itemplate.aspx
you should be able to take it from there, if that is what you want to do.
Following also is a simple example i wrote based on what you said here, i
hope it helps you.
Regards,
Alessandro Zifiglio
http://www.AsyncUI.net
<%@ Page Language="C#" %>
<%@ Register Assembly="AsyncUI" Namespace="AsyncUI.TestProjects"
TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
string blah = "paul";
protected void Page_Load(object sender, EventArgs e)
{
}
</script>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<cc1:MyWebCustomControl ID="MyWebCustomControl1" runat="server">
<LabelsTemplate>
<asp:Label ID="Label1" runat="server"
Text="Label1"></asp:Label>
<br />
<asp:Label ID="Label2" runat="server"
Text="Label2"></asp:Label>
</LabelsTemplate>
<FormFieldTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</FormFieldTemplate>
<ValidatorTemplate>
<span style="color:Green;font-weight:bold"><%= blah
%></span>
<asp:RequiredFieldValidator Display="Dynamic"
ID="RequiredFieldValidator1" ControlToValidate="TextBox1" runat="server"
ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
<asp:RequiredFieldValidator Display="Dynamic"
ControlToValidate="TextBox2" ID="RequiredFieldValidator2" runat="server"
ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
</ValidatorTemplate>
</cc1:MyWebCustomControl>
<asp:Button ID="Button1" runat="server" Text="Submit" />
</div>
</form>
</body>
</html>
//////////////////////////////////////////////
////// Custom control
//////////////////////////////////////////////////
using System;
using System.Text;
using System.Web.UI.WebControls;
using System.Drawing;
using System.ComponentModel;
using System.Web.UI;
namespace ControlTestCenter
{
public class MyWebCustomControl : WebControl
{
private ITemplate[] templates;
public MyWebCustomControl()
: base("table")
{
//Initialization code here.
// we want to expose 3 template
templates = new ITemplate[3];
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
writer.AddStyleAttribute(HtmlTextWriterStyle.VerticalAlign,
"top");
}
[PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(TemplateItem))]
public ITemplate FormFieldTemplate
{
get
{
return templates[0];
}
set
{
templates[0] = value;
}
}
[PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(TemplateItem))]
public ITemplate LabelsTemplate
{
get
{
return templates[1];
}
set
{
templates[1] = value;
}
}
[PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(TemplateItem))]
public ITemplate ValidatorTemplate
{
get
{
return templates[2];
}
set
{
templates[2] = value;
}
}
protected override void CreateChildControls()
{
base.CreateChildControls();
// use it to get to the naming Container
TemplateItem ti = new TemplateItem();
if (LabelsTemplate != null)
{
LabelsTemplate.InstantiateIn(ti.Cells[0]);
}
if (FormFieldTemplate != null)
{
FormFieldTemplate.InstantiateIn(ti.Cells[1]);
}
if (ValidatorTemplate != null)
{
ValidatorTemplate.InstantiateIn(ti.Cells[2]);
}
Controls.Add(ti);
}
}
public enum TemplateType
{
FormFields,
Labels,
Validator
}
[ToolboxItem(false)]
public class TemplateItem : TableRow, INamingContainer
{
private TemplateType itemTypeValue;
public TemplateItem()
{
Cells.Add(new TableCell());// labels
Cells.Add(new TableCell()); // formFields
Cells.Add(new TableCell()); // validators
}
public TemplateItem(TemplateType itemType)
{
this.itemTypeValue = itemType;
Cells.Add(new TableCell());
}
public virtual TemplateType ItemType
{
get
{
return itemTypeValue;
}
}
}
}