Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure a GridView CommandField to trigger Full Page Update in UpdatePanel

I have 2 user controls on my page. One is used for searching, and the other is used for editing (along with a few other things).

The user control that provides the search functionality uses a GridView to display the search results. This GridView has a CommandField used for editing (showEditButton="true").

I would like to place the GridView into an UpdatePanel so that paging through the search results will be smooth.

The thing is that when the user clicks the Edit Link (the CommandField) I need to preform a full page postback so that the search user control can be hidden and the edit user control can be displayed.

Edit: the reason I need to do a full page postback is because the edit user control is outside of the UpdatePanel that my GridView is in. It is not only outside the UpdatePanel, but it's in a completely different user control.

I have no idea how to add the CommandField as a full page postback trigger to the UpdatePanel. The PostBackTrigger (which is used to indicate the controls cause a full page postback) takes a ControlID as a parameter; however the CommandButton does not have an ID...and you can see why I'm having a problem with this.

Update on what else I've tried to solve the problem: I took a new approach to solving the problem.

In my new approach, I used a TemplateField instead of a CommandField. I placed a LinkButton control in the TemplateField and gave it a name. During the GridView's RowDataBound event I retrieved the LinkButton control and added it to the UpdatePanel's Triggers.

This is the ASP Markup for the UpdatePanel and the GridView

<asp:UpdatePanel ID="SearchResultsUpdateSection" runat="server">
  <ContentTemplate>
    <asp:GridView ID="SearchResultsGrid" runat="server" 
        AllowPaging="true" 
        AutoGenerateColumns="false">
      <Columns>
        <asp:TemplateField>
          <HeaderTemplate></HeaderTemplate>
          <ItemTemplate>
            <asp:LinkButton ID="Edit" runat="server" Text="Edit"></asp:LinkButton>
          </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField ......
      </Columns>
    </asp:GridView>
  </ContentTemplate>
</asp:UpdatePanel>

In my VB.NET code. I implemented a function that handles the GridView's RowDataBound event. In this method I find the LinkButton for the row being bound to, create a PostBackTrigger for the LinkButton, and add it to the UpdatePanel's Triggers. This means that a PostBackTrigger is created for every "edit" LinkButton in the GridView Edit: this did not create a PostBackTrigger for Every "edit" LinkButton because the ID is the same for all LinkButtons in the GridView.

Private Sub SearchResultsGrid_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles SearchResultsGrod.RowDataBound
    If e.Row.RowType = DataControlRowType.Header Then
       ''I am doing stuff here that does not pertain to the problem
    Else
        Dim editLink As LinkButton = CType(e.Row.FindControl("Edit"), LinkButton)
        If editLink IsNot Nothing Then
            Dim fullPageTrigger As New PostBackTrigger
            fullPageTrigger.ControlID = editLink.ID
            SearchResultsUpdateSection.Triggers.Add(fullPageTrigger)
        End If

    End If
End Sub

And instead of handling the GridView's RowEditing event for editing purposes i use the RowCommand instead.

Private Sub SearchResultsGrid_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles SearchResultsGrid.RowCommand
        RaiseEvent EditRecord(Me, New EventArgs())
End Sub

This new approach didn't work at all because all of the LinkButtons in the GridView have the same ID.

After reading the MSDN article on the UpdatePanel.Triggers Property I have the impression that Triggers can only be defined declaratively. This would mean that anything I did in the VB code wouldn't work.

Any advise would be greatly appreciated.

Thanks,

-Frinny

like image 395
Frinavale Avatar asked Aug 17 '09 19:08

Frinavale


4 Answers

To register a control as a trigger for a postback, use ScriptManager's RegisterPostBackControl Method.

     If editLink IsNot Nothing Then
           ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(editLink )
        End If

This methods works too for controls dynamically added within other controls. I had the same problem with my GridView. I've registered linkButton and imageButton of a TemplatedField row.

I use RowCreated Gridview's handler instead of RowDataBound handler : RowCreated is focused on parsing Gridview row's definition and creating the Gridview row's control structure, RowDataBound is focused on bind data to the row's controls created in the RowCreated. Also RowCreated is invoked automatically in both init and postback case, but RowDataBound is only invoke when the DataBind is called. Code

<asp:GridView ID="ContactsGridView" runat="server" AutoGenerateColumns="False"
        DataSourceID="ContactsContainerDataSource" EnableViewState="false"
        DataKeyNames="CompanyID,ContactId" AllowSorting="True" AllowPaging="true"
        OnRowCreated="ContactsGridView_RowCreated" PageSize="10" CssClass="GridSimple"
        OnRowCommand="ContactsGridView_RowCommand">
        <Columns>
               <asp:TemplateField HeaderStyle-CssClass="large" HeaderText="Contact" SortExpression="ContactNom">
                <ItemTemplate>
                    <asp:ImageButton ID="PreviewImageButton" runat="server" ImageUrl="../images/picto_pdf.gif"
                        CommandName="PreviewContact" CommandArgument=<%#Eval("ContactCode") %> BorderWidth="0"
                        ToolTip="View Pdf Document" />
                    <asp:LinkButton ID="ContactNamePreviewLinkButton" runat="server" CommandName="Select"
                        CommandArgument='<%#Eval("ContactCode") %>'><%#Eval("ContactName")%></asp:LinkButton>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>




    protected void ContactsGridView_RowCreated(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //Register download buttons as PostBack controls  (instead of AsyncPostback because of their updatepanel container))
            ImageButton ib = (ImageButton)e.Row.FindControl("PreviewImageButton");
            if (ib != null) ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(ib);
            LinkButton lb = (LinkButton)e.Row.FindControl("ContactNamePreviewLinkButton");
            if (lb != null) ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(lb);
        }

    }
    protected void ContactsGridView_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "PreviewContact")
        {

            _presenter.OnPreviewContactClicked((string)e.CommandArgument);
        }
    }
like image 74
sepho Avatar answered Nov 03 '22 03:11

sepho


In order to get around this problem I implemented a custom paging control which I placed above the GridView but still within the UpdatePanel. When the paging control is used the GridView's updated asynchronously. I set the GridView as a PostBackTrigger for the UpdatePanel. Now every control within the GridView causes a full page postback. Which means the edit control will cause a full page postback but so will sorting.

I feel a little defeated here, but at least I have a semi-working solution.

I'm still interested in hearing anyone's suggested solutions that may shed some light on fixing the problem.

-Frinny

like image 44
Frinavale Avatar answered Nov 03 '22 02:11

Frinavale


this post worked for me, it uses rowCreated, and scriptManager link text

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
    LinkButton lnk = e.Row.FindControl("LinkButton1") as LinkButton;
    if (e.Row.RowType == DataControlRowType.DataRow)
    {

        if (lnk != null)
        {
            ScriptManager1.RegisterPostBackControl(lnk);
        }
        //PostBackTrigger pb = new PostBackTrigger();

        //pb.ControlID = lnk.UniqueID;

    }

}

LinkButton lnk = gvMFDWise.FindControl("lnkbtn") as LinkButton; 
if (e.Row.RowType == DataControlRowType.DataRow) 
{ 
if (lnk != null) 
{ 
ScriptManager scriptManager2 = ToolkitScriptManager.GetCurrent(Page); 
scriptManager2.RegisterPostBackControl(lnk); 
} 

} 
like image 30
Brandon Culley Avatar answered Nov 03 '22 04:11

Brandon Culley


You can write these code also in Page_load out of postback. Every postback they reassgined and it should work I think

like image 1
Umit Akbas Avatar answered Nov 03 '22 03:11

Umit Akbas