views:

321

answers:

2

Hi, I am trying to get a dynamically loaded LinkButton to fire a postback event, which I then handle.

I have across Command, CommandName and CommandArgument - which looked real useful.. So I started messing with that, but currently cannot get to work as desired.

The links are rendered within a table that is created on the fly, here is the code to generate them:

    // The links are stored in Session since I was told that the objects need to remain intact across requests.
    LinkButton GetEditCardLink(string card)
    {
        if (!IsPostBack)
        {
            TW("Creating Link for Card '" + card + "' and Placing in Session.", true);
            LinkButton link = CreateEditLink(card);
            Business.Session.Set<LinkButton>("LinkedCards_EditLink_" + card, link);
        }
        return Business.Session.Get<LinkButton>("LinkedCards_EditLink_" + card);
    }

    // Here the link itself is created, note the ID and Command details are set.
    LinkButton CreateEditLink(string forCard)
    {
        TW("Setting Up Link for Card: " + forCard, true);
        LinkButton rtn = new LinkButton();
        rtn.ID = "Edit_" + forCard;
        rtn.Text = Resources.Header("EditDetails");
        rtn.CommandName = "Edit";
        rtn.CommandArgument = forCard;
        rtn.Command += new CommandEventHandler(RedirectToEdit);
        rtn.Attributes["style"] = "display: block; text-align:center;";
        return rtn;
    }

    // ... And the delegate I want called on PostBack..
    void RedirectToEdit(object sender, CommandEventArgs e)
    {
        TW("RedirectToEdit Called:\r\nName: " + e.CommandName + "\r\nArgument: " + e.CommandArgument);
    }

Trace confirms that the LinkButtons are being loaded correctly, and are only being creating once, so in theory they should be fine, but when I click the link, a PostBack is performed, but the RedirectToEdit method is not called?

All help gratefully received! :)

NOTE

Oh, I thought I should mention TW is just a utility method for Trace.Write/Warn :)

A: 

Here is my trial, and it worked :

protected void Page_Load(object sender, EventArgs e)
{
    //if (!IsPostBack)
    //{
        placeHolderAtPage.Controls.Add(CreateEditLink("forCard1"));
    //}
}

LinkButton CreateEditLink(string forCard)
{
    LinkButton rtn = new LinkButton();
    rtn.ID = "Edit_" + forCard;
    rtn.Text = "EditDetails";
    rtn.CommandName = "Edit";
    rtn.CommandArgument = forCard;
    rtn.Command += new CommandEventHandler(RedirectToEdit);
    rtn.Attributes["style"] = "display: block; text-align:center;";
    return rtn;
}

void RedirectToEdit(object sender, CommandEventArgs e)
{
    Response.Write("RedirectToEdit Called:\r\nName: " + e.CommandName + "\r\nArgument: " + e.CommandArgument);
}

If you decomment the IsPostBack line, RedirectToEdit will be useless. Only binding codes can be under IsPostBack control.

Canavar
The !IsPostBack Creates the Control and Adds it to Session, the control is then retrieved from Session on PostBack.. Since posting I have removed entirely and it makes no difference.. Thanks for the input :)
Rob Cooper
I called your method at PageLoad without IsPostBack control : placeHolderAtPage.Controls.Add(CreateEditLink("forCard1"));it worked !
Canavar
Myself, and others could replicate your working code, so I got digging elsewhere, turns out the call being made to get the data for the table was being called Async.. I figured this is likely to respond too late in the cycle. Switched to sync, all works fine. Thanks :)
Rob Cooper
+1  A: 

When you create a control that needs event handling you have to do it early enough in the processing that the event handler gets hooked up. Override OnInit for the page where you are creating the table and move the table creation code there. As @ScarletGarden suggests, you also need to add the control whether it's a PostBack or not. I believe that doing it in Page_Load is too late for the event to be detected if you add the control there.

Reference

tvanfosson
+1 from me for the OnInit.. I don't think it makes a real difference in this case, but it did get me thinking about the page lifecycle, which ended up finding the cause. I accepted ScarletGarden's answer through because he posted working code that may be useful to others.Thanks again, appreciated.
Rob Cooper