Click event does not fire - IPostBackEventHandler ?

Ahmet Gunes

Usenet Archive
Joined
Jan 31, 2003
Messages
16
Reaction score
0
Hi all,

I am developing a container control like a standard Div with a template property called Content. Unfortunately, although the button implements the IPostBackEventHandler interface (since it is the standard Button control) it's click event does not fire.

I am almost running crazy. I don't understand the problem. Could you please help?

Here is my code for my custom container:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;

namespace MyCustomControlLibrary {

[ParseChildren(true)]
[PersistChildren(false)]
public class MyDiv: WebControl {

private Control container = null;

protected override HtmlTextWriterTag TagKey {
get {
return HtmlTextWriterTag.Div;
}
}

[DefaultValue(null)]
[Browsable(false)]
[TemplateInstance(TemplateInstance.Single)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[NotifyParentProperty(true)]
public ITemplate Content {
get;
set;
}

protected override void OnInit(EventArgs e) {
if (Content != null) {
container = new HtmlGenericControl("div");
container.ID = ClientID + "_Content";
Content.InstantiateIn(container);
}
}

protected override void CreateChildControls {
base.CreateChildControls;

if (container != null) {
Controls.Add(container);
}
}
}
}

Here is a sample ASPX page that uses MyDiv:

<%@ Register Assembly="MyCustomControlLibrary" Namespace="MyCustomControlLibrary" TagPrefix="mcc" %>

<!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>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <mcc:MyDiv ID="MyDiv1" runat="server"> <Content> <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /> </Content> </mcc:MyDiv> </form> </body> </html>
 

Peter Bucher MVP

Usenet Archive
Joined
Jul 16, 2007
Messages
118
Reaction score
0
Hi Ahmet

I guess your Control have to implement "INamingContainer" to garant unique IDs and the Access from the ASP.NET-Engine.

Try this :)

To implement IPostBackEventHandler doesnt make any Sense for that control and your case, because _that_ Control isnt`t a PostBackEventHandler.
 

Ahmet Gunes

Usenet Archive
Joined
Jan 31, 2003
Messages
16
Reaction score
0
Thanks Peter,

Actually I have already tried implementing INamingContainer and it worked. :) I also found another way that also worked:

Replace the following lines

container = new HtmlGenericControl("div");
container.ID = ClientID + "_Content";
Content.InstantiateIn(container);
with

Content.InstantiateIn(this);

and remove the override of CreateChildControls.

But I didn't like these solutions since I need to call those content with the same ids in the client code. When INamingContainer is implemented the ids of the content controls are changed. My control is actually much more complicated and needs some inner container.

Actually, I saw a sample code at http://www.coolite.com which achieves this without implementing INamingContainer. If you wish, you may download the community edition as a Zip file and check the ContentPanel control. It does not implement INamingContainer in any way.

Thanks,

Ahmet
 

Peter Bucher MVP

Usenet Archive
Joined
Jul 16, 2007
Messages
118
Reaction score
0
Hi Ahmed
I also found another way that also worked:

Replace the following lines

container = new HtmlGenericControl("div");
container.ID = ClientID + "_Content";
Content.InstantiateIn(container);
with

Content.InstantiateIn(this);
Here you do manually what ASP.NET does if INamingContainer is implemented. And like you guess, thats not a good solution.

Whats the Problem with implementing INamingContainer?
Actually, I saw a sample code at http://www.coolite.com which achieves this without implementing INamingContainer. If you wish, you may download the community edition as a Zip file and check the ContentPanel control. It does not implement INamingContainer in any way.
I looked short at that Code, but doesent see the Reason - its way to complicated, IMO.
 

Ahmet Gunes

Usenet Archive
Joined
Jan 31, 2003
Messages
16
Reaction score
0
Hi Peter,

First of all, my container is actually a custom web control which does not output begin/end tags. To simplify things, I just put a sample div control. Therefore, I think my solution is not the same as implementing INamingContainer.

Now let me give you an example:
Assume the containing panel is named "pnl01", and my button control is "btn01". When I implement INamingContainer, the name and id of the button becomes "pnl01$btn01" and "pnl01_btn01", respectively. But for simplicity purposes I need to call the button as "btn01" in the client-side script.

Next, since those containers can be nested as many times as the page developer wishes, when you put pnl01 inside pnl02 then the name of the button becomes "pnl02$pnl01$btn01" which makes client-side scripting a tedious task. In addition, those new names adds to the total bytes sent to the client since there will be many textbox, dropdownlist or button controls in the form.

Another question: Is there any way to override the default behaviour of implementing INamingContainer?

Thanks,
 

Ahmet Gunes

Usenet Archive
Joined
Jan 31, 2003
Messages
16
Reaction score
0
Solved at last.

The point that I was missing is the execution order of the events. In order for a control to raise an event that control should be added to the Control tree first.

Hence the following code in the custom container control solved my problem:

protected override void OnInit(EventArgs e) {
base.OnInit(e);
if (Content != null) {
this.EnsureID;
container = new MyContainer;
container.ID = this.ID + "_Content";
Controls.Add(container);
Content.InstantiateIn(container);
}
}

Thanks,

Ahmet
 

Ion Lamasanu

Usenet Archive
Joined
Aug 5, 2008
Messages
1
Reaction score
0
You must implement RegisterRequiresRaiseEvent ( control) where control implements IPostBackEventHandler. This must be done in the control's load event. Also I must note that 'Only one server control can be registered per page request.' (MSDN cited) so only one control from those which implements IPostBackEventHandler will run its implemented RaisePostBackEvent. That control will be the last one which registers its instance with RegisterRequiresRaiseEvent from Page class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
548,042
Messages
3,104,223
Members
248,131
Latest member
Tonypshaw1

Latest Threads

Top