Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Full Postback programmatically from UpdatePanel

I have a GridView in an update panel. It's an inherited asp:GridView, so it has a little "export me" icon which does just that. It works by responding to an "export" click with an XLS file. The problem is that if you put the smart GridView inside an update panel, ASP.NET thinks the XLS file is to be written into the panel, which is obviously not what we want. For this, I need a full post-back every time.

My update panels are all programmatically generated

Solutions which don't work in this precise scenario (many of which are covered elsewhere on SO):

  1. In ASP.NET before version 4, if you left the ID off a control it would do a full postback even from within an update panel. My question is for the latest and greatest .NET 4 only.

  2. ScriptManager.RegisterPostBackControl looks promising. It does make the control post-back use the correct panel ID as the eventtarget, but doesn't otherwise help.

  3. Adding a PostBackTrigger to the Update panel. My update panels are generated programmatically, and MS state that this is not supported. My tests indicate that they're right: I tried it every way, but this does not work.

  4. I don't really like the idea of the smart GridView having to break out from itself, but I tried to make it put an extra control outside the updatePanel in these circumstances. The idea being to make a client-side click on my export button inside the panel be redirected by client javascript to simulate a click on that button outside the panel. However this doesn't work because I can't apparently add the "outside" control to the page - I get the "The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases." error.

  5. Using jQuery to shift the "export" control outside the panel. MS must have some list of controls which they think are "in" the panel, and the physical location within the DOM doesn't matter.

Does anyone have any ideas how to make that work? I know a lot of this should work, but that's not quite the same thing.

like image 416
philw Avatar asked Oct 31 '11 17:10

philw


2 Answers

For me, solution 3 works.

I dynamically add an UpdatePanel to the page, add a Button to the content template and associate a PostBackTrigger. I added a Click event handler in which I update a label (outside of the UpdatePanel) with the current date/time.

See my test setup below.

Markup

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:Panel ID="Panel1" runat="server"></asp:Panel>
<asp:Label ID="Label1" runat="server"></asp:Label>

Code Behind

protected void Page_Load(object sender, EventArgs e)
{
    string buttonId = "Button1";

    UpdatePanel updatePanel = new UpdatePanel();
    updatePanel.ID = "UpdatePanel1";

    Button button = new Button();
    button.ID = "Button1";
    button.Text = "Post back";
    button.Click += new EventHandler(button_Click);

    updatePanel.Triggers.Add(new PostBackTrigger() { ControlID = buttonId});

    updatePanel.ContentTemplateContainer.Controls.Add(button);

    Panel1.Controls.Add(updatePanel);
}

void button_Click(object sender, EventArgs e)
{
    Label1.Text = string.Format("Current date/time: {0}", DateTime.Now.ToString());
}

Hope this helps.

like image 115
jdavies Avatar answered Oct 29 '22 19:10

jdavies


I realise this was asked a year ago but if it helps anyone else, solution 2 worked for me.

((ScriptManager)this.Page.Master.FindControl("scrptmgr")).RegisterPostBackControl(lnkbtn);

The only way I can get it to work is if the control (in this case lnkbtn) is visible when the above line of code runs.

Edit - After more testing it now seems that this method only works if there are no postbacks in between registering the control to do a full postback and actually clicking the thing. The solution or hack is to register the control to do a full postback on each page load.

like image 22
codefish Avatar answered Oct 29 '22 19:10

codefish