Click event does not fire - IPostBackEventHandler ?

Discussion in 'ASP .Net Building Controls' started by Ahmet Gunes, Jun 30, 2008.

  1. Ahmet Gunes

    Ahmet Gunes Guest

    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:

    <%@ Page Debug="true" Language="C#" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="MyTestWebApplication._Default" %>
    <%@ 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>
     
    Ahmet Gunes, Jun 30, 2008
    #1
    1. Advertisements

  2. 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.

    --
    Gruss, Peter Bucher
    Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    http://www.aspnetzone.de/blogs/peterbucher/ - Auf den Spuren von .NET
     
    Peter Bucher [MVP], Jun 30, 2008
    #2
    1. Advertisements

  3. Ahmet Gunes

    Ahmet Gunes Guest

    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]" <>, haber iletisinde sunlari
    yazdi:upagn%...
    > 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.
    >
    > --
    > Gruss, Peter Bucher
    > Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland
    > http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    > http://www.aspnetzone.de/blogs/peterbucher/ - Auf den Spuren von .NET
     
    Ahmet Gunes, Jun 30, 2008
    #3
  4. 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.

    --
    Gruss, Peter Bucher
    Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    http://www.aspnetzone.de/blogs/peterbucher/ - Auf den Spuren von .NET
     
    Peter Bucher [MVP], Jul 1, 2008
    #4
  5. Ahmet Gunes

    Ahmet Gunes Guest

    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,


    "Peter Bucher [MVP]" <>, haber iletisinde sunlari
    yazdi:...
    > 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.
    >
    > --
    > Gruss, Peter Bucher
    > Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland
    > http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    > http://www.aspnetzone.de/blogs/peterbucher/ - Auf den Spuren von .NET
     
    Ahmet Gunes, Jul 1, 2008
    #5
  6. Ahmet Gunes

    Ahmet Gunes Guest

    [SOLVED] Re: Click event does not fire - IPostBackEventHandler ?

    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

    "Ahmet Gunes" <> wrote in message
    news:%...
    > 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,
    >
    >
    > "Peter Bucher [MVP]" <>, haber iletisinde
    > sunlari yazdi:...
    >> 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.
    >>
    >> --
    >> Gruss, Peter Bucher
    >> Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland
    >> http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    >> http://www.aspnetzone.de/blogs/peterbucher/ - Auf den Spuren von .NET

    >
    >
     
    Ahmet Gunes, Jul 1, 2008
    #6
  7. Ahmet Gunes

    Ion Lamasanu Guest

    RE: [SOLVED] Re: Click event does not fire - IPostBackEventHandler ?

    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.

    "Ahmet Gunes" wrote:

    > 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
    >
    > "Ahmet Gunes" <> wrote in message
    > news:%...
    > > 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,
    > >
    > >
    > > "Peter Bucher [MVP]" <>, haber iletisinde
    > > sunlari yazdi:...
    > >> 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.
    > >>
    > >> --
    > >> Gruss, Peter Bucher
    > >> Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland
    > >> http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    > >> http://www.aspnetzone.de/blogs/peterbucher/ - Auf den Spuren von .NET

    > >
    > >

    >
    >
    >
     
    Ion Lamasanu, Aug 5, 2008
    #7
    1. Advertisements

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Serdar Kalaycý

    asp button click event does not fire

    Serdar Kalaycý, Aug 12, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    4,718
  2. =?Utf-8?B?Ti4gU2hlaHphZA==?=

    change of session does not fire button click event for second time

    =?Utf-8?B?Ti4gU2hlaHphZA==?=, Apr 4, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    2,234
    Scott Allen
    Apr 5, 2005
  3. Mike
    Replies:
    11
    Views:
    4,630
    =?Utf-8?B?aGFuIHpoaXlhbmc=?=
    Sep 22, 2005
  4. Amy
    Replies:
    0
    Views:
    1,352
  5. Louis Somers
    Replies:
    3
    Views:
    3,752
    RichardPetheram
    Oct 17, 2008
  6. Rea Peleg

    asp button click event does not fire

    Rea Peleg, Aug 12, 2004, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    338
    David Alexander
    Aug 12, 2004
  7. Waldy

    LinkButton Click Event does not fire

    Waldy, Jan 2, 2008, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    326
    Waldy
    Jan 2, 2008
  8. Louis Somers

    Difference between Button click and IPostBackEventHandler

    Louis Somers, Sep 17, 2008, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    294
    Louis Somers
    Sep 17, 2008
Loading...