Give Markup support for Custom server control with public PlaceHolders properties
- by ravinsp
I have a custom server control with two public PlaceHolder properties exposed to outside. I can use this control in a page like this:
<cc1:MyControl ID="MyControl1" runat="server">
<TitleTemplate>
Title text and anything else
</TitleTemplate>
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</cc1:MyControl>
TitleTemplate and ContentTemplate are properties of type asp.net PlaceHolder class. Everything works fine. The control gets any content given to these custom properties and produces a custom HTML output around them.
If I want a Button1_Click event handler, I can attach the event handler in Page_Load like the following code. And it works.
protected void Page_Load(object sender, EventArgs e)
{
Button1.Click += new EventHandler(Button1_Click);
}
void Button1_Click(object sender, EventArgs e)
{
TextBox1.Text = "Button1 clicked";
}
But if try to attach the click event handler in aspx markup I get an error when running the application
"Compiler Error Message: CS0117:
'ASP.default_aspx' does not contain a
definition for 'Button1_Click'
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
AutoEventWireup is set to "true" in the page markup.
This happens only for child controls inside my custom control. I can programatically access child control correctly. Only problem is with event handler assignment from Markup. When I select the child Button in markup, the properties window only detects it as a < BUTTON. Not System.Web.UI.Controls.Button. It also doesn't display the "Events" tab. How can I give markup support for this scenario?
Here's code for MyControl class if needed. And remember, I'm not using any ITemplate types for this. The custom properties I provide are of type "PlaceHolder".
[ToolboxData("<{0}:MyControl runat=server>" +
"<TitleTemplate></TitleTemplate>" +
"<ContentTemplate></ContentTemplate>" +
"</{0}:MyControl>")]
public class MyControl : WebControl
{
PlaceHolder contentTemplate, titleTemplate;
public MyControl()
{
contentTemplate = new PlaceHolder();
titleTemplate = new PlaceHolder();
Controls.Add(contentTemplate);
Controls.Add(titleTemplate);
}
[Browsable(true)]
[TemplateContainer(typeof(PlaceHolder))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public PlaceHolder TitleTemplate
{
get { return titleTemplate; }
}
[Browsable(true)]
[TemplateContainer(typeof(PlaceHolder))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public PlaceHolder ContentTemplate
{
get { return contentTemplate; }
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write("<div>");
output.Write("<div class=\"title\">");
titleTemplate.RenderControl(output);
output.Write("</div>");
output.Write("<div class=\"content\">");
contentTemplate.RenderControl(output);
output.Write("</div>");
output.Write("</div>");
}
}