hi Paul, Somethings you want to know when nesting controls in this manner is
:
1. Make sure you set the attribute ParseChildren(false) which is the
default, and is not necessary if you inherit the Control class, but for eg.
if you should inherit the webcontrols class then this is true by, you want
to reset it to false.
2. Try to associate a ControlBuilder, in this way you can limit the kind of
controls that are permitted as child controls. This is because you are going
to be testing for the control type in the AddParsedSubObject method, so a
control type that is not supported wont get added into the controls
collection, and will throw an error.
3. For inline code block expressions syntax <%= %>, i was unable to get the
value. In effect AddParsedSubObject is not even called. Futher digging in
the default ControlBUilder class shows that for this type of code blocks, it
is not handled by the controlbuilder and there you go. I was however able to
efficiently get the value of databinding expression syntax<%# %> after the
databinding phase through the controls the controls collection. This is
handled by the ControlBuilder class and AddParsedSubOjbect fires accurately.
If you have difficulty with this and need to see some working code, let me
know.
4. Also when using inline code block expressions syntax <%= %>, the
framework wont allow you to add controls other than the controls already
present as child Controls nested declaratively. So if you need to add more
content you will be overriding the render method as you are currently doing
and as i am doing in the following sample code below.
5. The key method you are looking for is AddParsedSubObject
Follows is working sample code.
Regards,
Alessandro Zifiglio
http://www.AsyncUI.net
<%@ Page Language="C#" %>
<%@ Register Assembly="ControlTestCenter" Namespace="ControlTestCenter"
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 = "dood";
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:MyCustomControl ID="MyCustomControl1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator Display="dynamic"
ID="RequiredFieldValidator1" ControlToValidate="TextBox1" runat="server"
ErrorMessage="Textbox1 is required!"></asp:RequiredFieldValidator>
<%= blah %>
<asp:Button ID="Button1" Text="click me" runat="server" />
</cc1:MyCustomControl>
</div>
</form>
</body>
</html>
////////////////////////////////
////The custom control :
//////////////////////////////
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.Drawing;
namespace ControlTestCenter
{
public class MyControlBuilder : ControlBuilder
{
public override Type GetChildControlType(string tagName, IDictionary
attribs)
{
if (String.Compare(tagName, "asp:TextBox", true) == 0)
return typeof(TextBox);
else if (string.Compare(tagName, "asp:RequiredFieldValidator",
true) == 0)
return typeof(RequiredFieldValidator);
else if (string.Compare(tagName, "asp:Button", true) == 0)
return typeof(Button);
throw new Exception("The control you nested is not supported");
}
}
[ControlBuilderAttribute(typeof(MyControlBuilder))]
[ParseChildren(false)]
public class MyCustomControl : Control, INamingContainer
{
// Called at runtime when a child object is added to the collection.
protected override void AddParsedSubObject(object obj)
{
string s = obj.GetType().ToString();
if (obj is TextBox)
{
TextBox tb = (TextBox)obj;
Controls.Add(tb);
}
else if (obj is RequiredFieldValidator)
{
RequiredFieldValidator rFV = (RequiredFieldValidator)obj;
Controls.Add(rFV);
}
else if (obj is Button)
{
Button b = (Button)obj;
Controls.Add(b);
}
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
writer.Write("this is working, nicely and maintains layout!");
}
}
}