如何配置GridView CommandField以在UpdatePanel中触发整页更新

时间:2009-08-17 19:36:16

标签: asp.net asp.net-ajax

我的页面上有2个用户控件。 一个用于搜索,另一个用于编辑(以及其他一些东西)。

提供搜索功能的用户控件使用GridView显示搜索结果。这个GridView有一个用于编辑的CommandField(showEditButton =“true”)。

我想将GridView放入UpdatePanel,以便通过搜索结果进行分页。

当用户点击编辑链接(CommandField)时,我需要预先形成整页回发,以便隐藏搜索用户控件并显示编辑用户控件。

编辑:我需要进行整页回发的原因是因为编辑用户控件位于我的GridView所在的UpdatePanel之外。它不仅在UpdatePanel之外,而且在于一个完全不同的用户控制。

我不知道如何将CommandField作为整页回发触发器添加到UpdatePanel。 PostBackTrigger(用于指示控件导致整页回发)将ControlID作为参数;但是CommandButton没有ID ......你可以看出为什么我遇到这个问题。

更新我试图解决问题的其他内容: 我采取了一种新方法来解决问题。

在我的新方法中,我使用了TemplateField而不是CommandField。我在TemplateField中放置了一个LinkBut​​ton控件并为其命名。在GridView的RowDataBound事件期间,我检索了LinkBut​​ton控件并将其添加到UpdatePanel的触发器中。

这是UpdatePanel和GridView的ASP标记

<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>

在我的VB.NET代码中。我实现了一个处理GridView的RowDataBound事件的函数。在这个方法中,我找到了绑定行的LinkBut​​ton,为LinkBut​​ton创建一个PostBackTrigger,并将其添加到UpdatePanel的触发器。 这意味着为GridView中的每个“编辑”LinkBut​​ton创建了一个PostBackTrigger 编辑:这没有为每个“编辑”LinkBut​​ton创建一个PostBackTrigger,因为ID是相同的对于GridView中的所有LinkBut​​tons。

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

我没有处理GridView的RowEditing事件进行编辑,而是使用RowCommand。

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

这种新方法根本不起作用,因为GridView中的所有LinkBut​​tons都具有相同的ID。

在阅读UpdatePanel.Triggers Property上的MSDN文章后,我的印象是触发器只能以声明方式定义。这意味着我在VB代码中做的任何事都行不通。

任何建议都将不胜感激。

谢谢,

-Frinny

5 个答案:

答案 0 :(得分:9)

要将控件注册为回发的触发器,请使用ScriptManager的RegisterPostBackControl方法。

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

此方法也适用于在其他控件中动态添加的控件。 我的GridView遇到了同样的问题。我已经注册了TemplatedField行的linkBut​​ton和imageButton。

我使用RowCreated Gridview的处理程序而不是RowDataBound处理程序: RowCreated专注于解析Gridview行的定义并创建Gridview行的控制结构, RowDataBound专注于绑定数据到RowCreated中创建的行控件。 此外,在init和postback情况下都会自动调用RowCreated,但RowDataBound仅在调用DataBind时调用。 代码

<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);
        }
    }

答案 1 :(得分:2)

为了解决这个问题,我实现了一个自定义分页控件,它放在GridView上面,但仍在UpdatePanel中。使用分页控件时,GridView的异步更新。我将GridView设置为UpdatePanel的PostBackTrigger。现在,GridView中的每个控件都会导致整页回发。这意味着编辑控件将导致整页回发,但排序也是如此。

我觉得这里有点失败,但至少我有一个半工作的解决方案。

我仍然有兴趣听取任何人建议的解决方案,这些解决方案可能会解决问题。

-Frinny

答案 2 :(得分:2)

这篇文章对我有用,它使用rowCreated和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); 
} 

} 

答案 3 :(得分:0)

除非在页面加载之前执行此操作,否则无法使用RegisterPostBackControl或向触发器集合添加新的PostBackTrigger来向更新面板添加触发器。

必须在Oninitcomplete或oninit

中完成

答案 4 :(得分:0)

我从Brandon Culley提供的链接发布解决方案,我刚刚使用它,这是正确的方式来做到这一点并且工作得非常好。他的链接指向代码的C#版本,我发布了我用于VB的版本。如果有人错过了,请再次the link

当在gridview(RowCreated事件)中创建行时,找到该行中的链接按钮并通过scriptmanager将其注册为回发控件 - 这将允许它在单击时执行完整回发:

Protected Sub gridMusicLibrary_RowCreated(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gridMusicLibrary.RowCreated

    'clicking the link button needs to do a full 
    'postback outside of the update panel

    Dim lbtn As LinkButton = e.Row.FindControl("YourLinkButtonControlId")

    If e.Row.RowType = DataControlRowType.DataRow Then

        ScriptManager1.RegisterPostBackControl(lbtn)

    End If

End Sub