Search code examples
asp.netfile-uploadupdatepanelpostbackformview

FileUpload in FormView inside an UpdatePanel


The Scenario:
I have an ASP.Net webpage which I intend to use for letting the user(not the real users, but content manager basically) insert and edit the records in a table using a FormView. This FormView is inside an UpdatePanel, as I'm also using cascading dropdownlists to let the user select some values.

Now, this FormView also contains 4 FileUpload controls, and as you might know that these fileupload controls require a full postback since most browsers do not let Javascript access the disk. So, this problem would have been solved by doing something like:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <Triggers>
           <asp:PostBackTrigger ControlID="InsertButton" />
           <asp:PostBackTrigger ControlID="UpdateButton" />
           </Triggers>
                    <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

Edit: Forgot to add that the fileuploading takes place in the OnUpdating and OnInserting events of the SqlDataSource.

The Problem:
Since the InsertButton and the UpdateButton reside inside the Formview, I cannot directly access their ID's through markup. And MSDN says that:

Programmatically adding PostBackTrigger controls is not supported.

Please suggest some solution to make this work. Any insight on the matter is highly appreciated. Thanks.

P.S.- A workable solution for me was to set the UpdatePanel's PostBackTrigger as the whole FormView itself:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <Triggers>
           <asp:PostBackTrigger ControlID="FormView1" />
           </Triggers>
                    <ContentTemplate>....</ContentTemplate>
</asp:UpdatePanel>

But now due to a bit of change in requirements, this solution(if you call it a solution) is not acceptable.


Solution

  • Yay!! Finally got it to work!

    Here's How:

    Well contrary to what MSDN says, we can in fact add PostBack Triggers Programmatically. Not necessarily to the UpdatePanel, but to the ScriptManager.

    After hours of playing around, here's what worked:

    We are not able to access controls inside a FormView, untill the template has been rendered, so we can only add postback triggers after the formview's OnDataBound Event.

    protected void FormView1_DataBound(object sender, EventArgs e)
        {
            if (FormView1.CurrentMode == FormViewMode.Edit)
            {
                LinkButton lb = (LinkButton)FormView1.FindControl("UpdateButton");
                ScriptManager.GetCurrent(Page).RegisterPostBackControl(lb);
            }
    
            //Similarily you can put register the Insert LinkButton as well.
        }
    

    And now, if your UpdatePanel causes ConditionalUpdate, you can do something like this to make it work:

    The Markup:

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
               <ContentTemplate>..
                <EditItemTemplate>
                  ...
                <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" OnClick="Cause_PostBack"CommandName="Update">Update</asp:LinkButton>
                 ...
                </EditItemTemplate>
               ..</ContentTemplate>
    </asp:UpdatePanel>
    

    CodeBehind:

    //call this function as the OnClick Event Handler for the Controls you want to register as
    //triggers.
    protected void Cause_PostBack()
        {
            UpdatePanel1.Update();
        }
    

    Otherwise, if your situation allows it(as mine does), just set the UpdatePanel's UpdateMode="Always"