views:

27

answers:

2

Hi,

Currently struggling with a problem that I've encountered variations on in the past. At the moment a worthwhile solution escapes me, but it seems such an obvious issue that I can't help wondering whether or not there's a "best practice" approach I should adopt.

Without code, here's the issues in a nutshell:

  • page has databound control (a repeater) which isn't populated until user inputs data and clicks a button.
  • Repeater item template contains a button
  • User clicks button, page posts back. On load, the repeater is actually empty so event is never handled because the originating control no longer exists
  • Go back to the beginning of wretched cycle

I've confirmed that this is the problem because if you provide the repeater with some static data on page load, everything works fine. But of course that's no use because it has to be populated dynamically.

Is there a commonly approved way round this headache? I can store the data in session and re-use it on page load, but it seems terribly clumsy.

Cheers, Matt

+1  A: 

If the event is being fired by a button within a repeater then this would bubble up to the repeaters ItemCommand event. Using a buttons CommandName and CommandArgument parameters you can then identify which button was clicked and act accordingly. Below is some basic markup and code behind to demonstrate the approach:
HTML:

<asp:Repeater ID="rptTest" runat="server" onitemcommand="rptTest_ItemCommand" 
    onitemdatabound="rptTest_ItemDataBound">
    <ItemTemplate>
        <p>
            <asp:Button ID="btnTest" runat="server" />
        </p>
    </ItemTemplate>
</asp:Repeater>
<asp:Button ID="btnLoad" runat="server" Text="Load" onclick="btnLoad_Click" />

Code behind events:

protected void rptTest_ItemDataBound(object sender, RepeaterItemEventArgs e)
{

    Button button = (Button)e.Item.FindControl("btnTest");
    button.Text = string.Format("Button {0}", e.Item.DataItem.ToString());
    button.CommandName = e.Item.ItemIndex.ToString();
}

protected void rptTest_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    Response.Write(string.Format("Postback from button {0}", e.CommandName));
}

protected void btnLoad_Click(object sender, EventArgs e)
{
    List<int> list = new List<int>();
    list.Add(1);
    list.Add(2);
    list.Add(3);
    list.Add(4);
    rptTest.DataSource = list;
    rptTest.DataBind();
}

Hopefully i've understood the problem and this helps.

Andy Rose
+1  A: 

If any of your controls are created dynamically, then they have to be recreated during post back in order for the events etc to get hooked back up.

If this is the case, take a look at a control built by a guy named Denis Bauer. We use this with just some slight modifications and it's perfect.

Chris Lively