views:

2477

answers:

4

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

+1  A: 

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

Frinavale
A: 

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);
        }
    }
sepho
This method works fine for controls that are not dynamically added within other controls...For example, you cannot use this method for registering a link or button that is dynamically generated within a GridView. That is the whole reason why I posted this question: it is the problem. Please re-read the thread for more details on why and what I tried to do to get around this.
Frinavale
A: 

I have tried with ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(editLink ) but it only work first time. After a sorting or a paging (anything async) it doesn't work anymore.

Alexandru
Alexandru, what exactly did you try?
Frinavale
A: 

You can't add triggers to the update panel using either RegisterPostBackControl or by adding a new PostBackTrigger to the triggers collection unless you do it before the page load.

It has to be done in the Oninitcomplete or oninit

Poker Villain