0
votes

Hi everyone

This is my first post on stackoverflow (which btw is by far my favourite site for finding answers). After finally admitting defeat, I'm hoping someone can help me with this problem...

The question has already been asked several times, but none of the suggested solutions I found has helped. Apologies in advance for a lengthy post, but I want to avoid anyone wasting their time on suggesting things I tried already.

The code below worked until recently, and its structure has not been touched since (although unrelated changes were made to the child page). In any event, it suddenly stopped working. Now even the most simplified button won’t fire.

Setup

  • VS 2008 C#, IIS 7 (no changes in setup since way before it stopped working)

  • nested masterpage (main + 1 child)

  • dynamically loaded ucl with datalist in child page
    (i.e. MP => nested MP => child page => ucl => datalist => linkbutton)

  • linkbutton click event also resides in ucl


Problem

On LB click, the postback occurs ok, but the server-side click event never gets hit.

Code

page:

var ctrlX = base.LoadControl("~/somedir/someucl.ascx");

=> loads fine



ascx file (datalist stripped of all but the button):

<asp:DataList ID="dlX" RepeatLayout="Table" runat="server">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
    <tr>
        <td>
            <asp:LinkButton ID="btnX" OnClick="btnX_Click" CausesValidation="false" runat="server" />
        </td>
    </tr>               
</ItemTemplate>
<FooterTemplate></FooterTemplate>



codebehind:

protected void btnX_Click(object sender, EventArgs e)
{
// do something  
}



things tried

  • cleaning the solution
  • digging out a working backup and checking for code changes
    (found none affecting the structure or user control)

  • setting LinkButton CausesValidation true/false

  • stripping datalist and LinkButton down to bare essentials
  • adding AddressOf="btnX.click" to LinkButton
  • wrapping UpdatePanel one at a time with varying settings around
    usercontrol
    datalist
    linkbutton

  • reattaching eventhandler in usercontrol init / load event:

    IEnumerable<Control> controls = Utils.FlattenChildren(dlX);
    
    foreach (var button in controls.OfType(LinkButton)())
    {
        if (button.ID.Contains("btnX"))
            button.Click += new EventHandler(btnX_Click);
    }
    

    Wherever I add above code, all buttons are found and the event is attached, but click event doesn't fire ((LinkButton) = LinkButton inside <>; couldn't get it to display right, still struggling a bit with the editor) .

  • adding PostBackUrl manually in page load event

  • comparing the client ids between load/postback events => they always match



That's it. Right now, I can't think of what else to try or check (maybe something in the breakpoint context menu on postback?).

Because the ucl loads fine, and the postback is working ok, I suspect the problem is somewhere in the ucl, rather than the child page loading it. But maybe not.

If at all possible, I want to avoid workarounds (I need the button command argument, not shown above, and am not keen on solutions such as jquery with hidden field or query string).

Apart from anything, I would really like to understand what causes this.

Obviously, I'm missing something... Thanks to anyone taking their time reading/helping with this!



======== as requested additional codebehind =======

I've simplified the parent page code to a minimum, dropping all method calls, and as per Eoins suggestion moved the ucl load in the page's init event. The ucl code remains as shown above. The DL and LB show up fine, and on click the postback is triggered, ucl page load event is hit, but as before, the server click event is not hit.

    protected override void OnInit(EventArgs e)
    {
        var ctrlX = base.LoadControl("~/someucl.ascx");

        if (ctrlX == null)
            return;

        DataList dlX = (DataList)ctrlX.FindControl("dlX");

        if (dlX == null)
            return;

        DummyCollection x = new DummyCollection();

        x.Add(null); // ok since the test LB does not draw on the datasource
        dlX.DataSource = x;
        dlX.DataBind();
        pnlX.Controls.Add(ctrlX);

        base.OnInit(e);
    }
1
SO are you using VB.NET or C#? When do you add your control to the tree? - bash.d
When is your Repeater-instance bound? On every request, or auto-binding, at which life-cycle-step? When is the adding of the control done? - user57508
@bash.d: see my 1st bullet under setup (VS 2008 C#, IIS 7) - user2377420
the ucl is loaded on every page's page load event; the datalist resides permanently in the ucl, i.e. is not loaded dynamically - user2377420
I wasn't sure, because you are using funny things like AddressOf and <> in your bullet-lists, this is not C#! - bash.d

1 Answers

2
votes
var ctrlX = base.LoadControl("~/somedir/someucl.ascx");

Where exactly does this code live on your page?

You'll need to make sure you're creating it and adding it to the control collection early enough in the page lifecycle so that on subsequent postbacks its created & wired up in time. I.e. in the oninit event.

protected override OnInit(...)
{
   base.OnInit(...);

   var ctrlX = base.LoadControl("~/somedir/someucl.ascx");

   this.Controls.Add(ctrlX);
}