What seems to be happening is there is a postback executed - but none of the Click events fire. further the OnInit event of the inner (CalendarTile) Control never fires. Now what I am trying to do is when the user clicks on the inner CalendarTile it fires
a click event which should then Bubble up via the Home Page to the main page - when I will do some extra work.
The problem is that you create the CalendarTile in Home control but you never add him to Home.Controls collection and doing this you never make him be part of the Page Life Cycle.
To test just apply the following changes:
[DefaultProperty("Text")]
[ToolboxData("<{0}:Home runat=server></{0}:Home>")]
[Serializable()]
public class Home : WebControl, IPostBackEventHandler
{
public event EventHandler Click;
// child controls
CalendarTile tile = null;
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["Text"] = value;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
base.RenderContents(output);
}
protected override void CreateChildControls()
{
base.CreateChildControls();
this.Controls.Add(tile = new CalendarTile());
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
public void RaisePostBackEvent(string eventArgument)
{
if (Click != null) Click(this, EventArgs.Empty);
}
}
Nuno Gomes [visit my blog]
Portugal - Europe's West Coast
[Don't forget to click "Mark as Answer" on the post(s) that helped you.]
Solved it - eventually. I did what you said but in addition I had to change the class the control inherits from. Instead of using WebControl, IPostBackEventHandler I use CompositeControl. As soon as this is done then the Postback event fires.
It is explained in more detail in this blog entry I found; http://cstruter.com/blog/248 and here on MSDN http://msdn.microsoft.com/en-us/library/aa719644%28VS.71%29.aspx
PAULSC
Member
41 Points
22 Posts
Custom Control used in another Custom control Click Event(s) do not fire.
Feb 19, 2012 09:00 PM|LINK
I have a page with the following markup
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Diary.aspx.cs" Inherits="Calendar.Diary" %> <%@ Register assembly="CloudClientControls" namespace="CloudClientControls" tagprefix="cloud" %> <%@ Register Assembly="CloudClientControls" Namespace="CloudClientControls.Calendar" TagPrefix="cloudCal" %> <!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></title> <style type="text/css"> body { background: #eeeeee; font-size: .80em; font-family: "Helvetica Neue" , "Lucida Grande" , "Segoe UI" , Arial, Helvetica, Verdana, sans-serif; margin: 0px; padding: 0px; color: #696969; } #primaryDesktop { position:absolute; top:0px; left:0px; width:100%; height:100%; background:#EEEEEE; } .calendar_Tile { background:#fff; border:1px solid #DDDDDD; width:300px; height:150px; position:absolute; top:50%; margin-top:-75px; left:50%; margin-left:-150px; } .calendar_TitleBar { border-bottom:2px solid #000000; font-family:"Helvetica Neue" , "Lucida Grande" , "Segoe UI" , Arial, Helvetica, Verdana, sans-serif; font-size:20px; font-weight:bolder; color:#000000; height:25px; } </style> <script type="text/javascript" src="js/JQuery/jquery-1.7.js" ></script> </head> <body> <form id="form1" runat="server"> <div> <cloud:Home runat="server" /> </div> </form> </body> </html>The Home Control has the following code
[DefaultProperty("Text")] [ToolboxData("<{0}:Home runat=server></{0}:Home>")] [Serializable()] public class Home : WebControl, IPostBackEventHandler { public event EventHandler Click; // child controls CalendarTile tile = null; [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text"] = value; } } protected override void RenderContents(HtmlTextWriter output) { tile.RenderControl(output); base.RenderContents(output); } protected override void CreateChildControls() { base.CreateChildControls(); } protected override void AddAttributesToRender(HtmlTextWriter writer) { base.AddAttributesToRender(writer); } protected override void OnInit(EventArgs e) { tile = new CalendarTile(); base.OnInit(e); } public void RaisePostBackEvent(string eventArgument) { if (Click != null) Click(this, EventArgs.Empty); } }That control itself contains a 2nd Custom Control
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace CloudClientControls.Calendar { [DefaultProperty("Text")] [ToolboxData("<{0}:Calendar runat=server></{0}:Calendar>")] public class CalendarTile : Panel, IApplication, IPostBackEventHandler { // child controls Panel containerPanel = null; Panel tileTitleBar = null; Label tileTitleDay = null; Label tileTitleDate = null; [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text"] = value; } } protected override void RenderContents(HtmlTextWriter output) { if (containerPanel == null) CreateChildControls(); containerPanel.RenderControl(output); output.Write(Text); } protected override void OnInit(EventArgs e) { base.OnInit(e); } protected override void CreateChildControls() { containerPanel = new Panel() { ID = "CalendarPanel", CssClass = "calendar_Tile" }; if (Page == null) { Page p = (Page)HttpContext.Current.Handler; containerPanel.Attributes.Add("OnClick", p.ClientScript.GetPostBackEventReference(this, String.Empty)); } else { containerPanel.Attributes.Add("OnClick", Page.ClientScript.GetPostBackEventReference(this, String.Empty)); } this.tileTitleBar = new Panel() { ID = "tileTitleBar", CssClass = "calendar_TitleBar" }; this.tileTitleDay = new Label() { ID = "tileDay" }; this.tileTitleDate = new Label() { ID = "tileDate" }; tileTitleDay.Text = "SU"; tileTitleDay.Style.Add(HtmlTextWriterStyle.Position, "absolute"); tileTitleDay.Style.Add(HtmlTextWriterStyle.Left, "2px"); tileTitleDate.Text = DateTime.Now.ToString("dd"); tileTitleDate.Style.Add(HtmlTextWriterStyle.Position, "absolute"); tileTitleDate.Style.Add("Right", "2px"); tileTitleBar.Controls.Add(tileTitleDay); tileTitleBar.Controls.Add(tileTitleDate); containerPanel.Controls.Add(tileTitleBar); base.CreateChildControls(); } public event EventHandler Click; public void RaisePostBackEvent(string eventArgument) { if (Click != null) Click(this, EventArgs.Empty); } } }Once that is all put together it generates a page which looks like the following;
<body> <form method="post" action="Diary.aspx" id="form1"> <div class="aspNetHidden"> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJOTc1NDk4NzU2ZGS6tY7Rqs/W8YljiKjW+XrTh1ejAAVCVGcNFoM2bLMJrg==" /> </div> <div class="aspNetHidden"> <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" /> <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" /> </div> <div> <span><div> <div id="CalendarPanel" class="calendar_Tile" OnClick="__doPostBack('','')"> <div id="tileTitleBar" class="calendar_TitleBar"> <span id="tileDay" style="position:absolute;left:2px;">SU</span><span id="tileDate" style="Right:2px;position:absolute;">19</span> </div> </div> </div></span> </div> <script type="text/javascript"> //<![CDATA[ var theForm = document.forms['form1']; if (!theForm) { theForm = document.form1; } function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); } } //]]> </script> </form> </body>What seems to be happening is there is a postback executed - but none of the Click events fire. further the OnInit event of the inner (CalendarTile) Control never fires. Now what I am trying to do is when the user clicks on the inner CalendarTile it fires a click event which should then Bubble up via the Home Page to the main page - when I will do some extra work.
nmgomes
Participant
1392 Points
246 Posts
Re: Custom Control used in another Custom control Click Event(s) do not fire.
Feb 19, 2012 11:41 PM|LINK
Hi,
The problem is that you create the CalendarTile in Home control but you never add him to Home.Controls collection and doing this you never make him be part of the Page Life Cycle.
To test just apply the following changes:
[DefaultProperty("Text")] [ToolboxData("<{0}:Home runat=server></{0}:Home>")] [Serializable()] public class Home : WebControl, IPostBackEventHandler { public event EventHandler Click; // child controls CalendarTile tile = null; [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text"] = value; } } protected override void RenderContents(HtmlTextWriter output) { base.RenderContents(output); } protected override void CreateChildControls() { base.CreateChildControls(); this.Controls.Add(tile = new CalendarTile()); } protected override void AddAttributesToRender(HtmlTextWriter writer) { base.AddAttributesToRender(writer); } protected override void OnInit(EventArgs e) { base.OnInit(e); } public void RaisePostBackEvent(string eventArgument) { if (Click != null) Click(this, EventArgs.Empty); } }Portugal - Europe's West Coast
[Don't forget to click "Mark as Answer" on the post(s) that helped you.]
PAULSC
Member
41 Points
22 Posts
Re: Custom Control used in another Custom control Click Event(s) do not fire.
Feb 20, 2012 07:24 PM|LINK
I've tried that - the Home Control now has the following code in it's CreateChildControls Method
protected override void CreateChildControls() { base.CreateChildControls(); this.Controls.Add(tile = new CalendarTile()); }I've also modified the CreateChildControls Method of the CalendarTile Control to the following;
protected override void CreateChildControls() { base.CreateChildControls(); containerPanel = new Panel() { ID = "CalendarPanel", CssClass = "calendar_Tile" }; if (Page == null) { Page p = (Page)HttpContext.Current.Handler; containerPanel.Attributes.Add("OnClick", p.ClientScript.GetPostBackEventReference(this, String.Empty)); } else { containerPanel.Attributes.Add("OnClick", Page.ClientScript.GetPostBackEventReference(this, String.Empty)); } .
.
.
containerPanel.Controls.Add(tileTitleBar); this.Controls.Add(containerPanel); }
While it is doing a Postback - but the RaisePostBackEvent does not fire.
PAULSC
Member
41 Points
22 Posts
Re: Custom Control used in another Custom control Click Event(s) do not fire.
Feb 20, 2012 08:01 PM|LINK
Solved it - eventually. I did what you said but in addition I had to change the class the control inherits from. Instead of using WebControl, IPostBackEventHandler I use CompositeControl. As soon as this is done then the Postback event fires.
It is explained in more detail in this blog entry I found; http://cstruter.com/blog/248 and here on MSDN http://msdn.microsoft.com/en-us/library/aa719644%28VS.71%29.aspx