Nesting server controls with a composite control don't generate postback events

Discussion in 'ASP .Net Building Controls' started by Stephen Miller, Jul 25, 2003.

  1. Hi,

    I am new to web controls so please forgive me if my terminology is not
    100%!

    I am attempting to develop a composite control, based heavily on the
    Chapter 16 sample code in James Henry's "Developing .NET Custom
    Controls and Designers using C#" (see
    http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).

    The Control is designed to emulate a windows tab control by overriding
    the Render method to sending a customized HtmlTable.

    The control implements IpostBackDataHandler (with
    RaisePostDataChangedEvent & LoadPostData methods),
    IpostBackEventHandler (with RaisePostBackEvent method) and
    InamingContainer.

    This works fine, and I am very happy with the results, however when I
    nest any server controls that require PostBack, the nested controls
    fail to raise events.

    The ASPX for the custom control takes the following form. As an
    example, a standard Button control has been placed between the second
    tab's <cc1:Tab></cc1:Tab> tags.

    <cc1:TabControl id="myTab" runat="server">
    <cc1:Tab headertext="Tab1">First tab's content goes here</cc1:Tab>
    <cc1:Tab headertext="Tab2">
    Second tab's content includes a nested control:
    <asp:Button id="cmdTest" runat="server" Text="Click me!">
    </asp:Button>
    </cc1:Tab>
    <cc1:Tab headertext="tab3">Third tab's content goes here</cc1:Tab>
    </cc1:TabControl>

    In the codebehind, a function 'cmdTest_Click' has been declared to
    handle the 'cmdTest.Click' event. It is expected that clicking the
    button should call this function, however this doesn't happen.
    Interestingly, the page appears to make a round-trip to the server, it
    just fails to call events bound to the nested control. If the button
    is moved outside the custom control, it behaves as expected.

    What should I do to enable nested controls to generate their own
    events? If someone could post some code snippits, I would be much
    obliged!

    Thanks,

    Stephen
    Stephen Miller, Jul 25, 2003
    #1
    1. Advertising

  2. Stephen,

    Allow me to recommend "Developing Microsoft® ASP.NET Server Controls and
    Components" (http://www.microsoft.com/mspress/books/5728.asp). It's the
    best book I've read on the subject.

    --
    John Saunders
    Internet Engineer


    "Stephen Miller" <> wrote in message
    news:...
    > Hi,
    >
    > I am new to web controls so please forgive me if my terminology is not
    > 100%!
    >
    > I am attempting to develop a composite control, based heavily on the
    > Chapter 16 sample code in James Henry's "Developing .NET Custom
    > Controls and Designers using C#" (see
    > http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).
    >
    > The Control is designed to emulate a windows tab control by overriding
    > the Render method to sending a customized HtmlTable.
    >
    > The control implements IpostBackDataHandler (with
    > RaisePostDataChangedEvent & LoadPostData methods),
    > IpostBackEventHandler (with RaisePostBackEvent method) and
    > InamingContainer.
    >
    > This works fine, and I am very happy with the results, however when I
    > nest any server controls that require PostBack, the nested controls
    > fail to raise events.
    >
    > The ASPX for the custom control takes the following form. As an
    > example, a standard Button control has been placed between the second
    > tab's <cc1:Tab></cc1:Tab> tags.
    >
    > <cc1:TabControl id="myTab" runat="server">
    > <cc1:Tab headertext="Tab1">First tab's content goes here</cc1:Tab>
    > <cc1:Tab headertext="Tab2">
    > Second tab's content includes a nested control:
    > <asp:Button id="cmdTest" runat="server" Text="Click me!">
    > </asp:Button>
    > </cc1:Tab>
    > <cc1:Tab headertext="tab3">Third tab's content goes here</cc1:Tab>
    > </cc1:TabControl>
    >
    > In the codebehind, a function 'cmdTest_Click' has been declared to
    > handle the 'cmdTest.Click' event. It is expected that clicking the
    > button should call this function, however this doesn't happen.
    > Interestingly, the page appears to make a round-trip to the server, it
    > just fails to call events bound to the nested control. If the button
    > is moved outside the custom control, it behaves as expected.
    >
    > What should I do to enable nested controls to generate their own
    > events? If someone could post some code snippits, I would be much
    > obliged!
    >
    > Thanks,
    >
    > Stephen
    John Saunders, Jul 25, 2003
    #2
    1. Advertising

  3. Stephen Miller

    Teemu Keiski Guest

    Does your custom control implement INamingContainer interface? Implementing
    the interface is needed for postback routing with composite controls.

    --
    Teemu Keiski
    MCP, Designer/Developer
    Mansoft tietotekniikka Oy
    http://www.mansoft.fi

    AspInsiders Member, www.aspinsiders.com
    ASP.NET Forums Moderator, www.asp.net
    AspAlliance Columnist, www.aspalliance.com

    "Stephen Miller" <> wrote in message
    news:...
    > Hi,
    >
    > I am new to web controls so please forgive me if my terminology is not
    > 100%!
    >
    > I am attempting to develop a composite control, based heavily on the
    > Chapter 16 sample code in James Henry's "Developing .NET Custom
    > Controls and Designers using C#" (see
    > http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).
    >
    > The Control is designed to emulate a windows tab control by overriding
    > the Render method to sending a customized HtmlTable.
    >
    > The control implements IpostBackDataHandler (with
    > RaisePostDataChangedEvent & LoadPostData methods),
    > IpostBackEventHandler (with RaisePostBackEvent method) and
    > InamingContainer.
    >
    > This works fine, and I am very happy with the results, however when I
    > nest any server controls that require PostBack, the nested controls
    > fail to raise events.
    >
    > The ASPX for the custom control takes the following form. As an
    > example, a standard Button control has been placed between the second
    > tab's <cc1:Tab></cc1:Tab> tags.
    >
    > <cc1:TabControl id="myTab" runat="server">
    > <cc1:Tab headertext="Tab1">First tab's content goes here</cc1:Tab>
    > <cc1:Tab headertext="Tab2">
    > Second tab's content includes a nested control:
    > <asp:Button id="cmdTest" runat="server" Text="Click me!">
    > </asp:Button>
    > </cc1:Tab>
    > <cc1:Tab headertext="tab3">Third tab's content goes here</cc1:Tab>
    > </cc1:TabControl>
    >
    > In the codebehind, a function 'cmdTest_Click' has been declared to
    > handle the 'cmdTest.Click' event. It is expected that clicking the
    > button should call this function, however this doesn't happen.
    > Interestingly, the page appears to make a round-trip to the server, it
    > just fails to call events bound to the nested control. If the button
    > is moved outside the custom control, it behaves as expected.
    >
    > What should I do to enable nested controls to generate their own
    > events? If someone could post some code snippits, I would be much
    > obliged!
    >
    > Thanks,
    >
    > Stephen
    Teemu Keiski, Jul 26, 2003
    #3
  4. John,

    cmdTest.Click is declared in the codebehind as follows. I'm not sure
    that it's declaration is the problem, as the Server control (and it's
    click event) work fine when the Button control is moved outside my
    custom control.

    Placed normally on an ASPX page the button control works as expected:

    <this_works_fine>
    <asp:Button id="cmdTest" runat="server" Text="Generate event" />
    </this_works_fine>

    My problem is that when, the same control is nested as literal XML
    within my custom control, the control renders but is unable to call
    the cmdTest.Click event:

    <this_does_not_work>
    <cc1:TabControl id="tabTest" runat="server">
    <cc1:Tab>
    <asp:Button id="cmdTest" runat="server" Text="Generate event" />
    </cc1:Tab>
    </cc1:TabControl>
    </this_does_not_work>

    In this example, the codebehind for the Button control is:

    <codebehind>

    Protected WithEvents lblTest As
    System.Web.UI.HtmlControls.HtmlGenericControl
    Protected WithEvents cmdTest As System.Web.UI.WebControls.Button

    Private Sub cmdTest_Click(ByVal sender As System.Object, ByVal e As
    System.EventArgs) Handles cmdTest.Click
    lblTest.InnerHtml = "cmdTest Clicked"
    End Sub

    </codebehind>

    Note, this problem occurs with any server control nested as literal
    XML between my custom control's <cc1:Tab> & </cc1:Tab> tags.

    Thanks,

    Stephen


    "John Saunders" <> wrote in message news:<>...
    > Stephen,
    >
    > Where did you declare the cmdTest.Click handler? I don't see an OnClick in
    > the asp:Button declaration.
    >
    > --
    > John Saunders
    > Internet Engineer
    >
    >
    > "Stephen Miller" <> wrote in message
    > news:...
    > > Teemu,
    > >
    > > Yes, I have implemented the INamingContainer interface, although it
    > > doesn't appear to make any differnce to the performance of my control
    > > whether it is implemented or not.
    > >
    > > What I don't understand is that while my control happly renders HTML
    > > and server controls placed between my custom control tags
    > > <cc1:Tab></cc1:Tab>, server controls are unable to generate events. In
    > > my example, the nested literal control (if that's the right phrase)
    > > <cc1:Tab><asp:Button id="cmdTest" runat="server" /></cc1:Tab>, renders
    > > as a command button, makes a round trip to the server when clicked,
    > > but fails to call the function, declared to handle the 'cmdTest.Click'
    > > event. When I place the web control <asp:Button id="cmdTest"
    > > runat="server" /> outside my custom control it behaves as expeced.
    > >
    > > I have also been looking at the IParserAccessor interface and I wonder
    > > if this is relevant. Apparently, the IParserAccessor interface defines
    > > the method that ASP.NET server controls must implement to recognize
    > > when elements, either HTML or XML, are parsed.
    > >
    > > I have discovered that if I override the base implementation of the
    > > AddParsedSubObject method, with:
    > >
    > > void IParserAccessor.AddParsedSubObject(object obj) {
    > > }
    > >
    > > .. then all literal content between my controls <cc1:Tab></cc1:Tab>
    > > tags are dropped when the control is rendered. As such, I figure this
    > > is where that action is, but I am unable to find any information on
    > > how to force postback event handling for nested literal controls.
    > >
    > > Note, users of my custom control are free to add any HTML or XML
    > > literal markup between the <cc1:Tab></cc1:Tab> tab, so any solution
    > > must be very flexiable.
    > >
    > > Thanks for your help so far,
    > >
    > > Stephen
    > >
    > >
    > >
    > > "Teemu Keiski" <> wrote in message

    > news:<einOB#>...
    > > > Does your custom control implement INamingContainer interface?

    > Implementing
    > > > the interface is needed for postback routing with composite controls.
    > > >
    > > > --
    > > > Teemu Keiski
    > > > MCP, Designer/Developer
    > > > Mansoft tietotekniikka Oy
    > > > http://www.mansoft.fi
    > > >
    > > > AspInsiders Member, www.aspinsiders.com
    > > > ASP.NET Forums Moderator, www.asp.net
    > > > AspAlliance Columnist, www.aspalliance.com
    > > >
    > > > "Stephen Miller" <> wrote in message
    > > > news:...
    > > > > Hi,
    > > > >
    > > > > I am new to web controls so please forgive me if my terminology is not
    > > > > 100%!
    > > > >
    > > > > I am attempting to develop a composite control, based heavily on the
    > > > > Chapter 16 sample code in James Henry's "Developing .NET Custom
    > > > > Controls and Designers using C#" (see
    > > > > http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).
    > > > >
    > > > > The Control is designed to emulate a windows tab control by overriding
    > > > > the Render method to sending a customized HtmlTable.
    > > > >
    > > > > The control implements IpostBackDataHandler (with
    > > > > RaisePostDataChangedEvent & LoadPostData methods),
    > > > > IpostBackEventHandler (with RaisePostBackEvent method) and
    > > > > InamingContainer.
    > > > >
    > > > > This works fine, and I am very happy with the results, however when I
    > > > > nest any server controls that require PostBack, the nested controls
    > > > > fail to raise events.
    > > > >
    > > > > The ASPX for the custom control takes the following form. As an
    > > > > example, a standard Button control has been placed between the second
    > > > > tab's <cc1:Tab></cc1:Tab> tags.
    > > > >
    > > > > <cc1:TabControl id="myTab" runat="server">
    > > > > <cc1:Tab headertext="Tab1">First tab's content goes here</cc1:Tab>
    > > > > <cc1:Tab headertext="Tab2">
    > > > > Second tab's content includes a nested control:
    > > > > <asp:Button id="cmdTest" runat="server" Text="Click me!">
    > > > > </asp:Button>
    > > > > </cc1:Tab>
    > > > > <cc1:Tab headertext="tab3">Third tab's content goes here</cc1:Tab>
    > > > > </cc1:TabControl>
    > > > >
    > > > > In the codebehind, a function 'cmdTest_Click' has been declared to
    > > > > handle the 'cmdTest.Click' event. It is expected that clicking the
    > > > > button should call this function, however this doesn't happen.
    > > > > Interestingly, the page appears to make a round-trip to the server, it
    > > > > just fails to call events bound to the nested control. If the button
    > > > > is moved outside the custom control, it behaves as expected.
    > > > >
    > > > > What should I do to enable nested controls to generate their own
    > > > > events? If someone could post some code snippits, I would be much
    > > > > obliged!
    > > > >
    > > > > Thanks,
    > > > >
    > > > > Stephen
    Stephen Miller, Jul 27, 2003
    #4
  5. Stephen,

    If you've supplied enough of your control for me to reproduce this, then I
    missed it. Perhaps you could post a reproducer.

    I'd also suggest you set a breakpoint in your Page_Load and see whether
    cmdTest is ever set to anything.

    --
    John Saunders
    Internet Engineer


    "Stephen Miller" <> wrote in message
    news:...
    > John,
    >
    > cmdTest.Click is declared in the codebehind as follows. I'm not sure
    > that it's declaration is the problem, as the Server control (and it's
    > click event) work fine when the Button control is moved outside my
    > custom control.
    >
    > Placed normally on an ASPX page the button control works as expected:
    >
    > <this_works_fine>
    > <asp:Button id="cmdTest" runat="server" Text="Generate event" />
    > </this_works_fine>
    >
    > My problem is that when, the same control is nested as literal XML
    > within my custom control, the control renders but is unable to call
    > the cmdTest.Click event:
    >
    > <this_does_not_work>
    > <cc1:TabControl id="tabTest" runat="server">
    > <cc1:Tab>
    > <asp:Button id="cmdTest" runat="server" Text="Generate event" />
    > </cc1:Tab>
    > </cc1:TabControl>
    > </this_does_not_work>
    >
    > In this example, the codebehind for the Button control is:
    >
    > <codebehind>
    >
    > Protected WithEvents lblTest As
    > System.Web.UI.HtmlControls.HtmlGenericControl
    > Protected WithEvents cmdTest As System.Web.UI.WebControls.Button
    >
    > Private Sub cmdTest_Click(ByVal sender As System.Object, ByVal e As
    > System.EventArgs) Handles cmdTest.Click
    > lblTest.InnerHtml = "cmdTest Clicked"
    > End Sub
    >
    > </codebehind>
    >
    > Note, this problem occurs with any server control nested as literal
    > XML between my custom control's <cc1:Tab> & </cc1:Tab> tags.
    >
    > Thanks,
    >
    > Stephen
    >
    >
    > "John Saunders" <> wrote in message

    news:<>...
    > > Stephen,
    > >
    > > Where did you declare the cmdTest.Click handler? I don't see an OnClick

    in
    > > the asp:Button declaration.
    > >
    > > --
    > > John Saunders
    > > Internet Engineer
    > >
    > >
    > > "Stephen Miller" <> wrote in message
    > > news:...
    > > > Teemu,
    > > >
    > > > Yes, I have implemented the INamingContainer interface, although it
    > > > doesn't appear to make any differnce to the performance of my control
    > > > whether it is implemented or not.
    > > >
    > > > What I don't understand is that while my control happly renders HTML
    > > > and server controls placed between my custom control tags
    > > > <cc1:Tab></cc1:Tab>, server controls are unable to generate events. In
    > > > my example, the nested literal control (if that's the right phrase)
    > > > <cc1:Tab><asp:Button id="cmdTest" runat="server" /></cc1:Tab>, renders
    > > > as a command button, makes a round trip to the server when clicked,
    > > > but fails to call the function, declared to handle the 'cmdTest.Click'
    > > > event. When I place the web control <asp:Button id="cmdTest"
    > > > runat="server" /> outside my custom control it behaves as expeced.
    > > >
    > > > I have also been looking at the IParserAccessor interface and I wonder
    > > > if this is relevant. Apparently, the IParserAccessor interface defines
    > > > the method that ASP.NET server controls must implement to recognize
    > > > when elements, either HTML or XML, are parsed.
    > > >
    > > > I have discovered that if I override the base implementation of the
    > > > AddParsedSubObject method, with:
    > > >
    > > > void IParserAccessor.AddParsedSubObject(object obj) {
    > > > }
    > > >
    > > > .. then all literal content between my controls <cc1:Tab></cc1:Tab>
    > > > tags are dropped when the control is rendered. As such, I figure this
    > > > is where that action is, but I am unable to find any information on
    > > > how to force postback event handling for nested literal controls.
    > > >
    > > > Note, users of my custom control are free to add any HTML or XML
    > > > literal markup between the <cc1:Tab></cc1:Tab> tab, so any solution
    > > > must be very flexiable.
    > > >
    > > > Thanks for your help so far,
    > > >
    > > > Stephen
    > > >
    > > >
    > > >
    > > > "Teemu Keiski" <> wrote in message

    > > news:<einOB#>...
    > > > > Does your custom control implement INamingContainer interface?

    > > Implementing
    > > > > the interface is needed for postback routing with composite

    controls.
    > > > >
    > > > > --
    > > > > Teemu Keiski
    > > > > MCP, Designer/Developer
    > > > > Mansoft tietotekniikka Oy
    > > > > http://www.mansoft.fi
    > > > >
    > > > > AspInsiders Member, www.aspinsiders.com
    > > > > ASP.NET Forums Moderator, www.asp.net
    > > > > AspAlliance Columnist, www.aspalliance.com
    > > > >
    > > > > "Stephen Miller" <> wrote in message
    > > > > news:...
    > > > > > Hi,
    > > > > >
    > > > > > I am new to web controls so please forgive me if my terminology is

    not
    > > > > > 100%!
    > > > > >
    > > > > > I am attempting to develop a composite control, based heavily on

    the
    > > > > > Chapter 16 sample code in James Henry's "Developing .NET Custom
    > > > > > Controls and Designers using C#" (see
    > > > > > http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).
    > > > > >
    > > > > > The Control is designed to emulate a windows tab control by

    overriding
    > > > > > the Render method to sending a customized HtmlTable.
    > > > > >
    > > > > > The control implements IpostBackDataHandler (with
    > > > > > RaisePostDataChangedEvent & LoadPostData methods),
    > > > > > IpostBackEventHandler (with RaisePostBackEvent method) and
    > > > > > InamingContainer.
    > > > > >
    > > > > > This works fine, and I am very happy with the results, however

    when I
    > > > > > nest any server controls that require PostBack, the nested

    controls
    > > > > > fail to raise events.
    > > > > >
    > > > > > The ASPX for the custom control takes the following form. As an
    > > > > > example, a standard Button control has been placed between the

    second
    > > > > > tab's <cc1:Tab></cc1:Tab> tags.
    > > > > >
    > > > > > <cc1:TabControl id="myTab" runat="server">
    > > > > > <cc1:Tab headertext="Tab1">First tab's content goes

    here</cc1:Tab>
    > > > > > <cc1:Tab headertext="Tab2">
    > > > > > Second tab's content includes a nested control:
    > > > > > <asp:Button id="cmdTest" runat="server" Text="Click me!">
    > > > > > </asp:Button>
    > > > > > </cc1:Tab>
    > > > > > <cc1:Tab headertext="tab3">Third tab's content goes

    here</cc1:Tab>
    > > > > > </cc1:TabControl>
    > > > > >
    > > > > > In the codebehind, a function 'cmdTest_Click' has been declared to
    > > > > > handle the 'cmdTest.Click' event. It is expected that clicking the
    > > > > > button should call this function, however this doesn't happen.
    > > > > > Interestingly, the page appears to make a round-trip to the

    server, it
    > > > > > just fails to call events bound to the nested control. If the

    button
    > > > > > is moved outside the custom control, it behaves as expected.
    > > > > >
    > > > > > What should I do to enable nested controls to generate their own
    > > > > > events? If someone could post some code snippits, I would be much
    > > > > > obliged!
    > > > > >
    > > > > > Thanks,
    > > > > >
    > > > > > Stephen
    John Saunders, Jul 27, 2003
    #5
  6. John,

    If you are still interested, I have placed some source code at
    http://www.3la.com.au/TabControl.zip

    Note again, this code is based on sample code provided by James Henry
    at http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7.

    As a side issue, I have never been able to get debugging working on my
    machine (yes, I've wasted days and tried dozens of suggestion) so
    frustratingly, I can't set a breakpoint and test your suggestion.

    Thanks again,

    Stephen


    "John Saunders" <> wrote in message news:<eAydfG#>...
    > Stephen,
    >
    > If you've supplied enough of your control for me to reproduce this, then I
    > missed it. Perhaps you could post a reproducer.
    >
    > I'd also suggest you set a breakpoint in your Page_Load and see whether
    > cmdTest is ever set to anything.
    >
    > --
    > John Saunders
    > Internet Engineer
    >
    >
    > "Stephen Miller" <> wrote in message
    > news:...
    > > John,
    > >
    > > cmdTest.Click is declared in the codebehind as follows. I'm not sure
    > > that it's declaration is the problem, as the Server control (and it's
    > > click event) work fine when the Button control is moved outside my
    > > custom control.
    > >
    > > Placed normally on an ASPX page the button control works as expected:
    > >
    > > <this_works_fine>
    > > <asp:Button id="cmdTest" runat="server" Text="Generate event" />
    > > </this_works_fine>
    > >
    > > My problem is that when, the same control is nested as literal XML
    > > within my custom control, the control renders but is unable to call
    > > the cmdTest.Click event:
    > >
    > > <this_does_not_work>
    > > <cc1:TabControl id="tabTest" runat="server">
    > > <cc1:Tab>
    > > <asp:Button id="cmdTest" runat="server" Text="Generate event" />
    > > </cc1:Tab>
    > > </cc1:TabControl>
    > > </this_does_not_work>
    > >
    > > In this example, the codebehind for the Button control is:
    > >
    > > <codebehind>
    > >
    > > Protected WithEvents lblTest As
    > > System.Web.UI.HtmlControls.HtmlGenericControl
    > > Protected WithEvents cmdTest As System.Web.UI.WebControls.Button
    > >
    > > Private Sub cmdTest_Click(ByVal sender As System.Object, ByVal e As
    > > System.EventArgs) Handles cmdTest.Click
    > > lblTest.InnerHtml = "cmdTest Clicked"
    > > End Sub
    > >
    > > </codebehind>
    > >
    > > Note, this problem occurs with any server control nested as literal
    > > XML between my custom control's <cc1:Tab> & </cc1:Tab> tags.
    > >
    > > Thanks,
    > >
    > > Stephen
    > >
    > >
    > > "John Saunders" <> wrote in message

    > news:<>...
    > > > Stephen,
    > > >
    > > > Where did you declare the cmdTest.Click handler? I don't see an OnClick

    > in
    > > > the asp:Button declaration.
    > > >
    > > > --
    > > > John Saunders
    > > > Internet Engineer
    > > >
    > > >
    > > > "Stephen Miller" <> wrote in message
    > > > news:...
    > > > > Teemu,
    > > > >
    > > > > Yes, I have implemented the INamingContainer interface, although it
    > > > > doesn't appear to make any difference to the performance of my control
    > > > > whether it is implemented or not.
    > > > >
    > > > > What I don't understand is that while my control happly renders HTML
    > > > > and server controls placed between my custom control tags
    > > > > <cc1:Tab></cc1:Tab>, server controls are unable to generate events. In
    > > > > my example, the nested literal control (if that's the right phrase)
    > > > > <cc1:Tab><asp:Button id="cmdTest" runat="server" /></cc1:Tab>, renders
    > > > > as a command button, makes a round trip to the server when clicked,
    > > > > but fails to call the function, declared to handle the 'cmdTest.Click'
    > > > > event. When I place the web control <asp:Button id="cmdTest"
    > > > > runat="server" /> outside my custom control it behaves as expeced.
    > > > >
    > > > > I have also been looking at the IParserAccessor interface and I wonder
    > > > > if this is relevant. Apparently, the IParserAccessor interface defines
    > > > > the method that ASP.NET server controls must implement to recognize
    > > > > when elements, either HTML or XML, are parsed.
    > > > >
    > > > > I have discovered that if I override the base implementation of the
    > > > > AddParsedSubObject method, with:
    > > > >
    > > > > void IParserAccessor.AddParsedSubObject(object obj) {
    > > > > }
    > > > >
    > > > > .. then all literal content between my controls <cc1:Tab></cc1:Tab>
    > > > > tags are dropped when the control is rendered. As such, I figure this
    > > > > is where that action is, but I am unable to find any information on
    > > > > how to force postback event handling for nested literal controls.
    > > > >
    > > > > Note, users of my custom control are free to add any HTML or XML
    > > > > literal markup between the <cc1:Tab></cc1:Tab> tab, so any solution
    > > > > must be very flexiable.
    > > > >
    > > > > Thanks for your help so far,
    > > > >
    > > > > Stephen
    > > > >
    > > > >
    > > > >
    > > > > "Teemu Keiski" <> wrote in message

    > news:<einOB#>...
    > > > > > Does your custom control implement INamingContainer interface?

    > Implementing
    > > > > > the interface is needed for postback routing with composite

    > controls.
    > > > > >
    > > > > > --
    > > > > > Teemu Keiski
    > > > > > MCP, Designer/Developer
    > > > > > Mansoft tietotekniikka Oy
    > > > > > http://www.mansoft.fi
    > > > > >
    > > > > > AspInsiders Member, www.aspinsiders.com
    > > > > > ASP.NET Forums Moderator, www.asp.net
    > > > > > AspAlliance Columnist, www.aspalliance.com
    > > > > >
    > > > > > "Stephen Miller" <> wrote in message
    > > > > > news:...
    > > > > > > Hi,
    > > > > > >
    > > > > > > I am new to web controls so please forgive me if my terminology is

    > not
    > > > > > > 100%!
    > > > > > >
    > > > > > > I am attempting to develop a composite control, based heavily on

    > the
    > > > > > > Chapter 16 sample code in James Henry's "Developing .NET Custom
    > > > > > > Controls and Designers using C#" (see
    > > > > > > http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).
    > > > > > >
    > > > > > > The Control is designed to emulate a windows tab control by

    > overriding
    > > > > > > the Render method to sending a customized HtmlTable.
    > > > > > >
    > > > > > > The control implements IpostBackDataHandler (with
    > > > > > > RaisePostDataChangedEvent & LoadPostData methods),
    > > > > > > IpostBackEventHandler (with RaisePostBackEvent method) and
    > > > > > > InamingContainer.
    > > > > > >
    > > > > > > This works fine, and I am very happy with the results, however

    > when I
    > > > > > > nest any server controls that require PostBack, the nested

    > controls
    > > > > > > fail to raise events.
    > > > > > >
    > > > > > > The ASPX for the custom control takes the following form. As an
    > > > > > > example, a standard Button control has been placed between the

    > second
    > > > > > > tab's <cc1:Tab></cc1:Tab> tags.
    > > > > > >
    > > > > > > <cc1:TabControl id="myTab" runat="server">
    > > > > > > <cc1:Tab headertext="Tab1">First tab's content goes

    > here</cc1:Tab>
    > > > > > > <cc1:Tab headertext="Tab2">
    > > > > > > Second tab's content includes a nested control:
    > > > > > > <asp:Button id="cmdTest" runat="server" Text="Click me!">
    > > > > > > </asp:Button>
    > > > > > > </cc1:Tab>
    > > > > > > <cc1:Tab headertext="tab3">Third tab's content goes

    > here</cc1:Tab>
    > > > > > > </cc1:TabControl>
    > > > > > >
    > > > > > > In the codebehind, a function 'cmdTest_Click' has been declared to
    > > > > > > handle the 'cmdTest.Click' event. It is expected that clicking the
    > > > > > > button should call this function, however this doesn't happen.
    > > > > > > Interestingly, the page appears to make a round-trip to the

    > server, it
    > > > > > > just fails to call events bound to the nested control. If the

    > button
    > > > > > > is moved outside the custom control, it behaves as expected.
    > > > > > >
    > > > > > > What should I do to enable nested controls to generate their own
    > > > > > > events? If someone could post some code snippits, I would be much
    > > > > > > obliged!
    > > > > > >
    > > > > > > Thanks,
    > > > > > >
    > > > > > > Stephen
    Stephen Miller, Jul 28, 2003
    #6
  7. James,

    Thanks for that! The overrided CreateChildControls method is obviously
    the key, and my nested button control now correctly generates events.

    However, I think I have exposed a more complicated problem. If you
    nest within the custom control's tab a standard TextBox control
    ('txtRequired'), with a linked RequiredFieldValidator control
    ('valRequired'), the TextBox's properties do not appear to be
    available to the RequiredFieldValidator when rendering.

    The error message thrown is:
    "Unable to find control id 'txtRequired' referenced by the
    'ControlToValidate' property of 'valRequired'."

    Is there something I need to add to instatiate (if that the right
    term) the nested controls?

    My test page now includes:

    <test.aspx.vb>
    ...
    Protected WithEvents txtRequired As System.Web.UI.WebControls.TextBox
    Protected WithEvents valRequired As
    System.Web.UI.WebControls.RequiredFieldValidator
    ...
    </test.aspx.vb>

    <test.aspx>
    ...
    <cc1:Tab headertext="tab1">
    <asp:TextBox id="txtRequired" runat="server"></asp:TextBox>
    <asp:RequiredFieldValidator id="valRequired" runat="server"
    ErrorMessage="This field is Required."
    ControlToValidate="txtRequired">*</asp:RequiredFieldValidator>
    </cc1:Tab>
    ...
    </test.aspx>

    Thanks again for your help,

    Stephen



    "James Henry [BlueVision]" <developingdotnetcustomcontrols@bluevision> wrote in message news:<>...
    > Stephen,
    >
    > Make sure the TabControl class implements INamingContainer. The sample
    > code provided with the book does not. This interface does not define any
    > methods.
    >
    > Also, you need to add each Tab to the TabControl.Controls collection,
    > preferably during the creation of child controls.
    >
    > protected override void CreateChildControls()
    >
    > {
    > this.Controls.Clear();
    > foreach (Tab tab in tabs)
    > {
    > this.Controls.Add(tab);
    > }
    > }
    > Thanks,
    >
    > James
    >
    >
    >
    > "Stephen Miller" <> wrote in message
    > news:...
    > > John,
    > >
    > > Wow! The whole trace thing is new to me. Very interesting stuff! I've
    > > added the declaration <%@ Page Trace=true ... %> to my page and the
    > > line:
    > >
    > > Page.Trace.Write (" -> Class.Method");
    > >
    > > .. to each method in my control (TabControl.cs), plus the Page Load
    > > and cmdTest.Click handler in the codebehind (tabs.aspx.vb).
    > >
    > > Examining the Trace Infromation when clicking a tab (normal behaviour)
    > > provides the following sequence of events:
    > >
    > > Begin Init
    > > -> TabControl.OnInit
    > > End Init
    > > Begin LoadViewState
    > > -> TabControl.LoadViewState
    > > End LoadViewState
    > > Begin ProcessPostData
    > > -> TabControl.IPostBackDataHandler.LoadPostData
    > > End ProcessPostData
    > > -> tabs.aspx.vb Page Load
    > > Begin ProcessPostData Second Try
    > > End ProcessPostData Second Try
    > > Begin Raise ChangedEvents
    > > -> TabControl.IPostBackDataHandler.RaisePostDataChangedEvent
    > > End Raise ChangedEvents
    > > Begin Raise PostBackEvent
    > > -> TabControl.IPostBackDataHandler.RaisePostBackEvent
    > > -> TabControl.OnSelectedIndexChanged
    > > End Raise PostBackEvent
    > > Begin PreRender
    > > End PreRender
    > > -> TabControl.SaveViewState
    > > Begin SaveViewState
    > > -> TabControl.SaveViewState
    > > End SaveViewState
    > > Begin Render
    > > -> TabControl.RenderTabControl
    > > End Render
    > >
    > > When I click on the nested literal Button cmdTest, a trace placed on
    > > the cmdTest.Click handler cmdTest Click is not called. I also note
    > > that PostBackEvent does not call
    > > IPostBackDataHandler.RaisePostBackEvent>. The squence observed is :
    > >
    > > Begin Init
    > > -> TabControl.OnInit
    > > End Init
    > > Begin LoadViewState
    > > -> TabControl.LoadViewState
    > > End LoadViewState
    > > Begin ProcessPostData
    > > -> TabControl.IPostBackDataHandler.LoadPostData
    > > End ProcessPostData
    > > -> tabs.aspx.vb Page Load
    > > Begin ProcessPostData Second Try
    > > End ProcessPostData Second Try
    > > Begin Raise ChangedEvents
    > > -> TabControl.IPostBackDataHandler.RaisePostDataChangedEvent
    > > End Raise ChangedEvents
    > > Begin Raise PostBackEvent
    > > End Raise PostBackEvent
    > > Begin PreRender
    > > End PreRender
    > > -> TabControl.SaveViewState
    > > Begin SaveViewState
    > > -> TabControl.SaveViewState
    > > End SaveViewState
    > > Begin Render
    > > -> TabControl.RenderTabControl
    > > End Render
    > >
    > > Does this add any clarity?
    > >
    > > Stephen
    > >
    > > "John Saunders" <> wrote in message

    > news:<>...
    > > > Stephen,
    > > >
    > > > I'll take a look at your code a bit later today.
    > > >
    > > > In the meantime, I'd like to suggest you become familiar with using
    > > > Page.Trace.WriteLine. It can often be as good as a breakpoint.
    > > >
    > > > --
    > > > John Saunders
    > > > Internet Engineer
    > > >
    > > >
    > > >
    > > > "Stephen Miller" <> wrote in message
    > > > news:...
    > > > > John,
    > > > >
    > > > > If you are still interested, I have placed some source code at
    > > > > http://www.3la.com.au/TabControl.zip
    > > > >
    > > > > Note again, this code is based on sample code provided by James

    > Henry
    > > > > at http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7.
    > > > >
    > > > > As a side issue, I have never been able to get debugging working

    > on my
    > > > > machine (yes, I've wasted days and tried dozens of suggestion) so
    > > > > frustratingly, I can't set a breakpoint and test your suggestion.
    > > > >
    > > > > Thanks again,
    > > > >
    > > > > Stephen
    > > > >
    > > > >
    > > > > "John Saunders" <> wrote in message

    > news:<eAydfG#>...
    > > > > > Stephen,
    > > > > >
    > > > > > If you've supplied enough of your control for me to reproduce

    > this, then
    > I
    > > > > > missed it. Perhaps you could post a reproducer.
    > > > > >
    > > > > > I'd also suggest you set a breakpoint in your Page Load and see

    > whether
    > > > > > cmdTest is ever set to anything.
    > > > > >
    > > > > > --
    > > > > > John Saunders
    > > > > > Internet Engineer
    > > > > >
    > > > > >
    > > > > > "Stephen Miller" <> wrote in message
    > > > > > news:...
    > > > > > > John,
    > > > > > >
    > > > > > > cmdTest.Click is declared in the codebehind as follows. I'm

    > not sure
    > > > > > > that it's declaration is the problem, as the Server control

    > (and it's
    > > > > > > click event) work fine when the Button control is moved

    > outside my
    > > > > > > custom control.
    > > > > > >
    > > > > > > Placed normally on an ASPX page the button control works as

    > expected:
    > > > > > >
    > > > > > > <this works fine>
    > > > > > > <asp:Button id="cmdTest" runat="server" Text="Generate

    > event" />
    > > > > > > </this works fine>
    > > > > > >
    > > > > > > My problem is that when, the same control is nested as literal

    > XML
    > > > > > > within my custom control, the control renders but is unable to

    > call
    > > > > > > the cmdTest.Click event:
    > > > > > >
    > > > > > > <this does not work>
    > > > > > > <cc1:TabControl id="tabTest" runat="server">
    > > > > > > <cc1:Tab>
    > > > > > > <asp:Button id="cmdTest" runat="server"

    > Text="Generate event" />
    > > > > > > </cc1:Tab>
    > > > > > > </cc1:TabControl>
    > > > > > > </this does not work>
    > > > > > >
    > > > > > > In this example, the codebehind for the Button control is:
    > > > > > >
    > > > > > > <codebehind>
    > > > > > >
    > > > > > > Protected WithEvents lblTest As
    > > > > > > System.Web.UI.HtmlControls.HtmlGenericControl
    > > > > > > Protected WithEvents cmdTest As

    > System.Web.UI.WebControls.Button
    > > > > > >
    > > > > > > Private Sub cmdTest Click(ByVal sender As System.Object,

    > ByVal e As
    > > > > > > System.EventArgs) Handles cmdTest.Click
    > > > > > > lblTest.InnerHtml = "cmdTest Clicked"
    > > > > > > End Sub
    > > > > > >
    > > > > > > </codebehind>
    > > > > > >
    > > > > > > Note, this problem occurs with any server control nested as

    > literal
    > > > > > > XML between my custom control's <cc1:Tab> & </cc1:Tab> tags.
    > > > > > >
    > > > > > > Thanks,
    > > > > > >
    > > > > > > Stephen
    > > > > > >
    > > > > > >
    > > > > > > "John Saunders" <> wrote in

    > message
    > news:<>...
    > > > > > > > Stephen,
    > > > > > > >
    > > > > > > > Where did you declare the cmdTest.Click handler? I don't see

    > an
    > > > OnClick
    > > > in
    > > > > > > > the asp:Button declaration.
    > > > > > > >
    > > > > > > > --
    > > > > > > > John Saunders
    > > > > > > > Internet Engineer
    > > > > > > >
    > > > > > > >
    > > > > > > > "Stephen Miller" <> wrote in message
    > > > > > > > news:...
    > > > > > > > > Teemu,
    > > > > > > > >
    > > > > > > > > Yes, I have implemented the INamingContainer interface,

    > although
    > it
    > > > > > > > > doesn't appear to make any difference to the performance

    > of my
    > control
    > > > > > > > > whether it is implemented or not.
    > > > > > > > >
    > > > > > > > > What I don't understand is that while my control happly

    > renders
    > HTML
    > > > > > > > > and server controls placed between my custom control tags
    > > > > > > > > <cc1:Tab></cc1:Tab>, server controls are unable to

    > generate
    > events. In
    > > > > > > > > my example, the nested literal control (if that's the

    > right
    > phrase)
    > > > > > > > > <cc1:Tab><asp:Button id="cmdTest" runat="server"

    > /></cc1:Tab>,
    > renders
    > > > > > > > > as a command button, makes a round trip to the server when

    > clicked,
    > > > > > > > > but fails to call the function, declared to handle the

    > 'cmdTest.Click'
    > > > > > > > > event. When I place the web control <asp:Button

    > id="cmdTest"
    > > > > > > > > runat="server" /> outside my custom control it behaves

    > as expeced.
    > > > > > > > >
    > > > > > > > > I have also been looking at the IParserAccessor interface

    > and I
    > wonder
    > > > > > > > > if this is relevant. Apparently, the IParserAccessor

    > interface
    > defines
    > > > > > > > > the method that ASP.NET server controls must implement to

    > recognize
    > > > > > > > > when elements, either HTML or XML, are parsed.
    > > > > > > > >
    > > > > > > > > I have discovered that if I override the base

    > implementation of
    > the
    > > > > > > > > AddParsedSubObject method, with:
    > > > > > > > >
    > > > > > > > > void IParserAccessor.AddParsedSubObject(object obj) {
    > > > > > > > > }
    > > > > > > > >
    > > > > > > > > .. then all literal content between my controls

    > <cc1:Tab></cc1:Tab>
    > > > > > > > > tags are dropped when the control is rendered. As such, I

    > figure
    > this
    > > > > > > > > is where that action is, but I am unable to find any

    > information
    > on
    > > > > > > > > how to force postback event handling for nested literal

    > controls.
    > > > > > > > >
    > > > > > > > > Note, users of my custom control are free to add any HTML

    > or XML
    > > > > > > > > literal markup between the <cc1:Tab></cc1:Tab> tab, so any

    > solution
    > > > > > > > > must be very flexiable.
    > > > > > > > >
    > > > > > > > > Thanks for your help so far,
    > > > > > > > >
    > > > > > > > > Stephen
    > > > > > > > >
    > > > > > > > >
    > > > > > > > >
    > > > > > > > > "Teemu Keiski" <> wrote in message

    > news:<einOB#>...
    > > > > > > > > > Does your custom control implement INamingContainer

    > interface?
    > Implementing
    > > > > > > > > > the interface is needed for postback routing with

    > composite
    > controls.
    > > > > > > > > >
    > > > > > > > > > --
    > > > > > > > > > Teemu Keiski
    > > > > > > > > > MCP, Designer/Developer
    > > > > > > > > > Mansoft tietotekniikka Oy
    > > > > > > > > > http://www.mansoft.fi
    > > > > > > > > >
    > > > > > > > > > AspInsiders Member, www.aspinsiders.com
    > > > > > > > > > ASP.NET Forums Moderator, www.asp.net
    > > > > > > > > > AspAlliance Columnist, www.aspalliance.com
    > > > > > > > > >
    > > > > > > > > > "Stephen Miller" <> wrote in message
    > > > > > > > > > news:...
    > > > > > > > > > > Hi,
    > > > > > > > > > >
    > > > > > > > > > > I am new to web controls so please forgive me if my
    > > > terminology is
    > > > not
    > > > > > > > > > > 100%!
    > > > > > > > > > >
    > > > > > > > > > > I am attempting to develop a composite control, based

    > heavily
    > > > on
    > > > the
    > > > > > > > > > > Chapter 16 sample code in James Henry's "Developing

    > .NET
    > Custom
    > > > > > > > > > > Controls and Designers using C#" (see
    > > > > > > > > > >

    > http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).
    > > > > > > > > > >
    > > > > > > > > > > The Control is designed to emulate a windows tab

    > control by
    > overriding
    > > > > > > > > > > the Render method to sending a customized HtmlTable.
    > > > > > > > > > >
    > > > > > > > > > > The control implements IpostBackDataHandler (with
    > > > > > > > > > > RaisePostDataChangedEvent & LoadPostData methods),
    > > > > > > > > > > IpostBackEventHandler (with RaisePostBackEvent method)

    > and
    > > > > > > > > > > InamingContainer.
    > > > > > > > > > >
    > > > > > > > > > > This works fine, and I am very happy with the results,

    > however
    > when I
    > > > > > > > > > > nest any server controls that require PostBack, the

    > nested
    > controls
    > > > > > > > > > > fail to raise events.
    > > > > > > > > > >
    > > > > > > > > > > The ASPX for the custom control takes the following

    > form. As
    > an
    > > > > > > > > > > example, a standard Button control has been placed

    > between the
    > second
    > > > > > > > > > > tab's <cc1:Tab></cc1:Tab> tags.
    > > > > > > > > > >
    > > > > > > > > > > <cc1:TabControl id="myTab" runat="server">
    > > > > > > > > > > <cc1:Tab headertext="Tab1">First tab's content goes

    > here</cc1:Tab>
    > > > > > > > > > > <cc1:Tab headertext="Tab2">
    > > > > > > > > > > Second tab's content includes a nested control:
    > > > > > > > > > > <asp:Button id="cmdTest" runat="server"

    > Text="Click me!">
    > > > > > > > > > > </asp:Button>
    > > > > > > > > > > </cc1:Tab>
    > > > > > > > > > > <cc1:Tab headertext="tab3">Third tab's content goes

    > here</cc1:Tab>
    > > > > > > > > > > </cc1:TabControl>
    > > > > > > > > > >
    > > > > > > > > > > In the codebehind, a function 'cmdTest Click' has been

    > declared to
    > > > > > > > > > > handle the 'cmdTest.Click' event. It is expected that

    > clicking
    > the
    > > > > > > > > > > button should call this function, however this doesn't

    > happen.
    > > > > > > > > > > Interestingly, the page appears to make a round-trip

    > to the
    > server, it
    > > > > > > > > > > just fails to call events bound to the nested control.

    > If the
    > button
    > > > > > > > > > > is moved outside the custom control, it behaves as

    > expected.
    > > > > > > > > > >
    > > > > > > > > > > What should I do to enable nested controls to generate

    > their
    > own
    > > > > > > > > > > events? If someone could post some code snippits, I

    > would be
    > much
    > > > > > > > > > > obliged!
    > > > > > > > > > >
    > > > > > > > > > > Thanks,
    > > > > > > > > > >
    > > > > > > > > > > Stephen

    > --
    Stephen Miller, Aug 6, 2003
    #7
  8. Both the validator control and the control being validated need to be within
    the same INamingContainer. This sucks. I found this when I wanted them in
    separate templates. Didn't work.
    --
    John Saunders
    Internet Engineer


    "Stephen Miller" <> wrote in message
    news:...
    > James,
    >
    > Thanks for that! The overrided CreateChildControls method is obviously
    > the key, and my nested button control now correctly generates events.
    >
    > However, I think I have exposed a more complicated problem. If you
    > nest within the custom control's tab a standard TextBox control
    > ('txtRequired'), with a linked RequiredFieldValidator control
    > ('valRequired'), the TextBox's properties do not appear to be
    > available to the RequiredFieldValidator when rendering.
    >
    > The error message thrown is:
    > "Unable to find control id 'txtRequired' referenced by the
    > 'ControlToValidate' property of 'valRequired'."
    >
    > Is there something I need to add to instatiate (if that the right
    > term) the nested controls?
    >
    > My test page now includes:
    >
    > <test.aspx.vb>
    > ...
    > Protected WithEvents txtRequired As System.Web.UI.WebControls.TextBox
    > Protected WithEvents valRequired As
    > System.Web.UI.WebControls.RequiredFieldValidator
    > ...
    > </test.aspx.vb>
    >
    > <test.aspx>
    > ...
    > <cc1:Tab headertext="tab1">
    > <asp:TextBox id="txtRequired" runat="server"></asp:TextBox>
    > <asp:RequiredFieldValidator id="valRequired" runat="server"
    > ErrorMessage="This field is Required."
    > ControlToValidate="txtRequired">*</asp:RequiredFieldValidator>
    > </cc1:Tab>
    > ...
    > </test.aspx>
    >
    > Thanks again for your help,
    >
    > Stephen
    >
    >
    >
    > "James Henry [BlueVision]" <developingdotnetcustomcontrols@bluevision>

    wrote in message news:<>...
    > > Stephen,
    > >
    > > Make sure the TabControl class implements INamingContainer. The sample
    > > code provided with the book does not. This interface does not define any
    > > methods.
    > >
    > > Also, you need to add each Tab to the TabControl.Controls collection,
    > > preferably during the creation of child controls.
    > >
    > > protected override void CreateChildControls()
    > >
    > > {
    > > this.Controls.Clear();
    > > foreach (Tab tab in tabs)
    > > {
    > > this.Controls.Add(tab);
    > > }
    > > }
    > > Thanks,
    > >
    > > James
    > >
    > >
    > >
    > > "Stephen Miller" <> wrote in message
    > > news:...
    > > > John,
    > > >
    > > > Wow! The whole trace thing is new to me. Very interesting stuff! I've
    > > > added the declaration <%@ Page Trace=true ... %> to my page and the
    > > > line:
    > > >
    > > > Page.Trace.Write (" -> Class.Method");
    > > >
    > > > .. to each method in my control (TabControl.cs), plus the Page Load
    > > > and cmdTest.Click handler in the codebehind (tabs.aspx.vb).
    > > >
    > > > Examining the Trace Infromation when clicking a tab (normal behaviour)
    > > > provides the following sequence of events:
    > > >
    > > > Begin Init
    > > > -> TabControl.OnInit
    > > > End Init
    > > > Begin LoadViewState
    > > > -> TabControl.LoadViewState
    > > > End LoadViewState
    > > > Begin ProcessPostData
    > > > -> TabControl.IPostBackDataHandler.LoadPostData
    > > > End ProcessPostData
    > > > -> tabs.aspx.vb Page Load
    > > > Begin ProcessPostData Second Try
    > > > End ProcessPostData Second Try
    > > > Begin Raise ChangedEvents
    > > > -> TabControl.IPostBackDataHandler.RaisePostDataChangedEvent
    > > > End Raise ChangedEvents
    > > > Begin Raise PostBackEvent
    > > > -> TabControl.IPostBackDataHandler.RaisePostBackEvent
    > > > -> TabControl.OnSelectedIndexChanged
    > > > End Raise PostBackEvent
    > > > Begin PreRender
    > > > End PreRender
    > > > -> TabControl.SaveViewState
    > > > Begin SaveViewState
    > > > -> TabControl.SaveViewState
    > > > End SaveViewState
    > > > Begin Render
    > > > -> TabControl.RenderTabControl
    > > > End Render
    > > >
    > > > When I click on the nested literal Button cmdTest, a trace placed on
    > > > the cmdTest.Click handler cmdTest Click is not called. I also note
    > > > that PostBackEvent does not call
    > > > IPostBackDataHandler.RaisePostBackEvent>. The squence observed is :
    > > >
    > > > Begin Init
    > > > -> TabControl.OnInit
    > > > End Init
    > > > Begin LoadViewState
    > > > -> TabControl.LoadViewState
    > > > End LoadViewState
    > > > Begin ProcessPostData
    > > > -> TabControl.IPostBackDataHandler.LoadPostData
    > > > End ProcessPostData
    > > > -> tabs.aspx.vb Page Load
    > > > Begin ProcessPostData Second Try
    > > > End ProcessPostData Second Try
    > > > Begin Raise ChangedEvents
    > > > -> TabControl.IPostBackDataHandler.RaisePostDataChangedEvent
    > > > End Raise ChangedEvents
    > > > Begin Raise PostBackEvent
    > > > End Raise PostBackEvent
    > > > Begin PreRender
    > > > End PreRender
    > > > -> TabControl.SaveViewState
    > > > Begin SaveViewState
    > > > -> TabControl.SaveViewState
    > > > End SaveViewState
    > > > Begin Render
    > > > -> TabControl.RenderTabControl
    > > > End Render
    > > >
    > > > Does this add any clarity?
    > > >
    > > > Stephen
    > > >
    > > > "John Saunders" <> wrote in message

    > > news:<>...
    > > > > Stephen,
    > > > >
    > > > > I'll take a look at your code a bit later today.
    > > > >
    > > > > In the meantime, I'd like to suggest you become familiar with using
    > > > > Page.Trace.WriteLine. It can often be as good as a breakpoint.
    > > > >
    > > > > --
    > > > > John Saunders
    > > > > Internet Engineer
    > > > >
    > > > >
    > > > >
    > > > > "Stephen Miller" <> wrote in message
    > > > > news:...
    > > > > > John,
    > > > > >
    > > > > > If you are still interested, I have placed some source code at
    > > > > > http://www.3la.com.au/TabControl.zip
    > > > > >
    > > > > > Note again, this code is based on sample code provided by James

    > > Henry
    > > > > > at http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7.
    > > > > >
    > > > > > As a side issue, I have never been able to get debugging working

    > > on my
    > > > > > machine (yes, I've wasted days and tried dozens of suggestion) so
    > > > > > frustratingly, I can't set a breakpoint and test your suggestion.
    > > > > >
    > > > > > Thanks again,
    > > > > >
    > > > > > Stephen
    > > > > >
    > > > > >
    > > > > > "John Saunders" <> wrote in message

    > > news:<eAydfG#>...
    > > > > > > Stephen,
    > > > > > >
    > > > > > > If you've supplied enough of your control for me to reproduce

    > > this, then
    > > I
    > > > > > > missed it. Perhaps you could post a reproducer.
    > > > > > >
    > > > > > > I'd also suggest you set a breakpoint in your Page Load and see

    > > whether
    > > > > > > cmdTest is ever set to anything.
    > > > > > >
    > > > > > > --
    > > > > > > John Saunders
    > > > > > > Internet Engineer
    > > > > > >
    > > > > > >
    > > > > > > "Stephen Miller" <> wrote in message
    > > > > > > news:...
    > > > > > > > John,
    > > > > > > >
    > > > > > > > cmdTest.Click is declared in the codebehind as follows. I'm

    > > not sure
    > > > > > > > that it's declaration is the problem, as the Server control

    > > (and it's
    > > > > > > > click event) work fine when the Button control is moved

    > > outside my
    > > > > > > > custom control.
    > > > > > > >
    > > > > > > > Placed normally on an ASPX page the button control works as

    > > expected:
    > > > > > > >
    > > > > > > > <this works fine>
    > > > > > > > <asp:Button id="cmdTest" runat="server" Text="Generate

    > > event" />
    > > > > > > > </this works fine>
    > > > > > > >
    > > > > > > > My problem is that when, the same control is nested as literal

    > > XML
    > > > > > > > within my custom control, the control renders but is unable to

    > > call
    > > > > > > > the cmdTest.Click event:
    > > > > > > >
    > > > > > > > <this does not work>
    > > > > > > > <cc1:TabControl id="tabTest" runat="server">
    > > > > > > > <cc1:Tab>
    > > > > > > > <asp:Button id="cmdTest" runat="server"

    > > Text="Generate event" />
    > > > > > > > </cc1:Tab>
    > > > > > > > </cc1:TabControl>
    > > > > > > > </this does not work>
    > > > > > > >
    > > > > > > > In this example, the codebehind for the Button control is:
    > > > > > > >
    > > > > > > > <codebehind>
    > > > > > > >
    > > > > > > > Protected WithEvents lblTest As
    > > > > > > > System.Web.UI.HtmlControls.HtmlGenericControl
    > > > > > > > Protected WithEvents cmdTest As

    > > System.Web.UI.WebControls.Button
    > > > > > > >
    > > > > > > > Private Sub cmdTest Click(ByVal sender As System.Object,

    > > ByVal e As
    > > > > > > > System.EventArgs) Handles cmdTest.Click
    > > > > > > > lblTest.InnerHtml = "cmdTest Clicked"
    > > > > > > > End Sub
    > > > > > > >
    > > > > > > > </codebehind>
    > > > > > > >
    > > > > > > > Note, this problem occurs with any server control nested as

    > > literal
    > > > > > > > XML between my custom control's <cc1:Tab> & </cc1:Tab> tags.
    > > > > > > >
    > > > > > > > Thanks,
    > > > > > > >
    > > > > > > > Stephen
    > > > > > > >
    > > > > > > >
    > > > > > > > "John Saunders" <> wrote in

    > > message
    > > news:<>...
    > > > > > > > > Stephen,
    > > > > > > > >
    > > > > > > > > Where did you declare the cmdTest.Click handler? I don't see

    > > an
    > > > > OnClick
    > > > > in
    > > > > > > > > the asp:Button declaration.
    > > > > > > > >
    > > > > > > > > --
    > > > > > > > > John Saunders
    > > > > > > > > Internet Engineer
    > > > > > > > >
    > > > > > > > >
    > > > > > > > > "Stephen Miller" <> wrote in message
    > > > > > > > > news:...
    > > > > > > > > > Teemu,
    > > > > > > > > >
    > > > > > > > > > Yes, I have implemented the INamingContainer interface,

    > > although
    > > it
    > > > > > > > > > doesn't appear to make any difference to the performance

    > > of my
    > > control
    > > > > > > > > > whether it is implemented or not.
    > > > > > > > > >
    > > > > > > > > > What I don't understand is that while my control happly

    > > renders
    > > HTML
    > > > > > > > > > and server controls placed between my custom control tags
    > > > > > > > > > <cc1:Tab></cc1:Tab>, server controls are unable to

    > > generate
    > > events. In
    > > > > > > > > > my example, the nested literal control (if that's the

    > > right
    > > phrase)
    > > > > > > > > > <cc1:Tab><asp:Button id="cmdTest" runat="server"

    > > /></cc1:Tab>,
    > > renders
    > > > > > > > > > as a command button, makes a round trip to the server when

    > > clicked,
    > > > > > > > > > but fails to call the function, declared to handle the

    > > 'cmdTest.Click'
    > > > > > > > > > event. When I place the web control <asp:Button

    > > id="cmdTest"
    > > > > > > > > > runat="server" /> outside my custom control it behaves

    > > as expeced.
    > > > > > > > > >
    > > > > > > > > > I have also been looking at the IParserAccessor interface

    > > and I
    > > wonder
    > > > > > > > > > if this is relevant. Apparently, the IParserAccessor

    > > interface
    > > defines
    > > > > > > > > > the method that ASP.NET server controls must implement to

    > > recognize
    > > > > > > > > > when elements, either HTML or XML, are parsed.
    > > > > > > > > >
    > > > > > > > > > I have discovered that if I override the base

    > > implementation of
    > > the
    > > > > > > > > > AddParsedSubObject method, with:
    > > > > > > > > >
    > > > > > > > > > void IParserAccessor.AddParsedSubObject(object obj) {
    > > > > > > > > > }
    > > > > > > > > >
    > > > > > > > > > .. then all literal content between my controls

    > > <cc1:Tab></cc1:Tab>
    > > > > > > > > > tags are dropped when the control is rendered. As such, I

    > > figure
    > > this
    > > > > > > > > > is where that action is, but I am unable to find any

    > > information
    > > on
    > > > > > > > > > how to force postback event handling for nested literal

    > > controls.
    > > > > > > > > >
    > > > > > > > > > Note, users of my custom control are free to add any HTML

    > > or XML
    > > > > > > > > > literal markup between the <cc1:Tab></cc1:Tab> tab, so any

    > > solution
    > > > > > > > > > must be very flexiable.
    > > > > > > > > >
    > > > > > > > > > Thanks for your help so far,
    > > > > > > > > >
    > > > > > > > > > Stephen
    > > > > > > > > >
    > > > > > > > > >
    > > > > > > > > >
    > > > > > > > > > "Teemu Keiski" <> wrote in message

    > > news:<einOB#>...
    > > > > > > > > > > Does your custom control implement INamingContainer

    > > interface?
    > > Implementing
    > > > > > > > > > > the interface is needed for postback routing with

    > > composite
    > > controls.
    > > > > > > > > > >
    > > > > > > > > > > --
    > > > > > > > > > > Teemu Keiski
    > > > > > > > > > > MCP, Designer/Developer
    > > > > > > > > > > Mansoft tietotekniikka Oy
    > > > > > > > > > > http://www.mansoft.fi
    > > > > > > > > > >
    > > > > > > > > > > AspInsiders Member, www.aspinsiders.com
    > > > > > > > > > > ASP.NET Forums Moderator, www.asp.net
    > > > > > > > > > > AspAlliance Columnist, www.aspalliance.com
    > > > > > > > > > >
    > > > > > > > > > > "Stephen Miller" <> wrote in message
    > > > > > > > > > > news:...
    > > > > > > > > > > > Hi,
    > > > > > > > > > > >
    > > > > > > > > > > > I am new to web controls so please forgive me if my
    > > > > terminology is
    > > > > not
    > > > > > > > > > > > 100%!
    > > > > > > > > > > >
    > > > > > > > > > > > I am attempting to develop a composite control, based

    > > heavily
    > > > > on
    > > > > the
    > > > > > > > > > > > Chapter 16 sample code in James Henry's "Developing

    > > .NET
    > > Custom
    > > > > > > > > > > > Controls and Designers using C#" (see
    > > > > > > > > > > >

    > > http://www.bluevisionsoftware.com/WebSite/BookInfo.aspx?ID=7 ).
    > > > > > > > > > > >
    > > > > > > > > > > > The Control is designed to emulate a windows tab

    > > control by
    > > overriding
    > > > > > > > > > > > the Render method to sending a customized HtmlTable.
    > > > > > > > > > > >
    > > > > > > > > > > > The control implements IpostBackDataHandler (with
    > > > > > > > > > > > RaisePostDataChangedEvent & LoadPostData methods),
    > > > > > > > > > > > IpostBackEventHandler (with RaisePostBackEvent method)

    > > and
    > > > > > > > > > > > InamingContainer.
    > > > > > > > > > > >
    > > > > > > > > > > > This works fine, and I am very happy with the results,

    > > however
    > > when I
    > > > > > > > > > > > nest any server controls that require PostBack, the

    > > nested
    > > controls
    > > > > > > > > > > > fail to raise events.
    > > > > > > > > > > >
    > > > > > > > > > > > The ASPX for the custom control takes the following

    > > form. As
    > > an
    > > > > > > > > > > > example, a standard Button control has been placed

    > > between the
    > > second
    > > > > > > > > > > > tab's <cc1:Tab></cc1:Tab> tags.
    > > > > > > > > > > >
    > > > > > > > > > > > <cc1:TabControl id="myTab" runat="server">
    > > > > > > > > > > > <cc1:Tab headertext="Tab1">First tab's content goes

    > > here</cc1:Tab>
    > > > > > > > > > > > <cc1:Tab headertext="Tab2">
    > > > > > > > > > > > Second tab's content includes a nested control:
    > > > > > > > > > > > <asp:Button id="cmdTest" runat="server"

    > > Text="Click me!">
    > > > > > > > > > > > </asp:Button>
    > > > > > > > > > > > </cc1:Tab>
    > > > > > > > > > > > <cc1:Tab headertext="tab3">Third tab's content goes

    > > here</cc1:Tab>
    > > > > > > > > > > > </cc1:TabControl>
    > > > > > > > > > > >
    > > > > > > > > > > > In the codebehind, a function 'cmdTest Click' has been

    > > declared to
    > > > > > > > > > > > handle the 'cmdTest.Click' event. It is expected that

    > > clicking
    > > the
    > > > > > > > > > > > button should call this function, however this doesn't

    > > happen.
    > > > > > > > > > > > Interestingly, the page appears to make a round-trip

    > > to the
    > > server, it
    > > > > > > > > > > > just fails to call events bound to the nested control.

    > > If the
    > > button
    > > > > > > > > > > > is moved outside the custom control, it behaves as

    > > expected.
    > > > > > > > > > > >
    > > > > > > > > > > > What should I do to enable nested controls to generate

    > > their
    > > own
    > > > > > > > > > > > events? If someone could post some code snippits, I

    > > would be
    > > much
    > > > > > > > > > > > obliged!
    > > > > > > > > > > >
    > > > > > > > > > > > Thanks,
    > > > > > > > > > > >
    > > > > > > > > > > > Stephen

    > > --
    John Saunders, Aug 6, 2003
    #8
    1. Advertising

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. sleigh
    Replies:
    1
    Views:
    2,687
    sleigh
    Feb 12, 2004
  2. Chad
    Replies:
    0
    Views:
    222
  3. David Boike

    Child controls in Composite Controls not firing events

    David Boike, Aug 7, 2003, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    312
    David Boike
    Aug 7, 2003
  4. Wael_Bakr

    stop postback in postback events for server controls ??

    Wael_Bakr, Nov 30, 2005, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    497
    Wael_Bakr
    Nov 30, 2005
  5. Trans
    Replies:
    10
    Views:
    302
    Sean O'Halpin
    Sep 16, 2005
Loading...

Share This Page