pageindexchanging 后,嵌套的 gridview 不会保持展开状态

nested gridview does not stay expanded after pageindexchanging

我有一个嵌套的 gridview,我希望它在用户单击其中一个分页值后保持展开状态。我在网上找到了一个示例,但它对我不起作用。

如果有人能看出我错在哪里,我将不胜感激。

这是我的 JavaScript 函数,expands/hides 嵌套网格。它工作正常。这也是我设置隐藏值以识别展开哪个网格的地方。

function DivExpandCollapse(RecipientID) {
    var div = document.getElementById(RecipientID);
    var img = document.getElementById('img' + RecipientID);

    if (div.style.display == "none") {
        div.style.display = "inline";
        img.src = "Images/minus.png";
        $("#recdevgvIsExpanded").val("1");
    } else {
        div.style.display = "none";
        img.src = "Images/plus.png";
        $("#recdevgvIsExpanded").val("");
    }
}

此函数识别要扩展的网格并且应该扩展它。 它进入 if 语句并且 recipientID 是正确的。 我构建了 divimg 元素的 id 来设置它们。

$(document).ready(function () {
    $("[id*=recdevgvIsExpanded]").each(function () {
        if ($(this).val() == "1") {
            var div = $(this).parent().closest("div");
            $tds = div.find("td");
            var recipientID = $tds.siblings(":first").text();
            var div2 = document.getElementById('div' + recipientID);
            var img = document.getElementById('imgdiv' + recipientID);

            div2.style.display = "inline";
            img.src = "Images/minus.png";
        }
    });
});

这是通过网格行设置扩展值的隐藏代码。它还将正确的嵌套网格设置为 'expanded'.

protected void Page_Load(object sender, EventArgs e)
{

    if (!IsPostBack)
    {
        //Get Recipient Info from Database
        populateRecipientInfoGrid();
    }//end if IsPostBack

    //For Re expanding the expanded rows
    foreach (GridViewRow row in RecipientInfoGridView.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            HiddenField IsExpanded = row.FindControl("recdevgvIsExpanded") as HiddenField;
            IsExpanded.Value = Request.Form[IsExpanded.UniqueID];
        }
    }
}

这是 PageIndexChanging 事件。它正确地更新了数据。

protected void RecipientDeviceGridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView tgvRecipientDevice = (GridView)sender;    
    tgvRecipientDevice.PageIndex = e.NewPageIndex;
    int tiRecipientID = Convert.ToInt32((tgvRecipientDevice.Parent.FindControl("rigvLblRecipientID") as Label).Text);
    populateDeviceGrid(tgvRecipientDevice, tiRecipientID);
}

这是标记

<asp:GridView ID="RecipientInfoGridView" runat="server" 
    AllowPaging="True" 
    PageSize="10" 
    AutoGenerateColumns="False" 
    Caption="Recipient Information" 
    CaptionAlign="Top"
    CssClass="grid" 
    HorizontalAlign="Left" 
    ShowFooter="True"
    ShowHeaderWhenEmpty="True" 
    DataKeyNames="RecipientID"
    OnPageIndexChanging="RecipientInfoGridView_PageIndexChanging">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <a href="javascript:DivExpandCollapse('div<%# Eval("RecipientID")%>');">
                    <img id="imgdiv<%# Eval("RecipientID")%>" alt="" 
                        width="25px" border="0" src="Images/plus.png" />
                </a>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="RecipientID">
            <ItemTemplate>
                <asp:Label ID="rigvLblRecipientID" runat="server" 
                    Text='<%# Bind("RecipientID") %>' 
                    ClientIDMode="Static">

                </asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <tr>
            <td colspan="100%">
                <div id="div<%# Eval("RecipientID") %>" style="display: none">
                    <asp:GridView ID="RecipientDeviceGridView" runat="server" 
                        AutoGenerateColumns="false" 
                        CssClass="grid" 
                        ShowFooter="true" 
                        Caption="Device Information" 
                        CaptionAlign="Top" 
                        AllowPaging="true" 
                        PageSize="1" 
                        HorizontalAlign="Left" 
                        OnPageIndexChanging="RecipientDeviceGridView_PageIndexChanging">
                        <Columns>
                            <asp:TemplateField HeaderText="DeviceID">
                                <ItemTemplate>
                                    <asp:Label ID="recdevgvLblDeviceID" runat="server" 
                                        Text='<%# Bind("DeviceID") %>'>
                                    </asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Device" ItemStyle-Wrap="false">
                                <ItemTemplate>
                                    <asp:Label ID="recdevgvLblDeviceName" runat="server" 
                                        Text='<%# Bind("DeviceName") %>'>
                                    </asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Service Provider">
                                <ItemTemplate>
                                    <asp:Label ID="recdevgvLblServiceName" runat="server" 
                                        Text='<%# Bind("ServiceName") %>'>
                                    </asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Address">
                                <ItemTemplate>
                                    <asp:Label ID="recdevgvLblAddress" runat="server" 
                                        Text='<%# Bind("Address") %>'>
                                    </asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Active">
                                <ItemTemplate>
                                    <asp:Label ID="recdevgvLblActive" runat="server" 
                                        Text='<%# (Boolean.Parse(Eval("Active").ToString())) ? "Yes" : "No" %>'>
                                    </asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Action" 
                                ShowHeader="False" 
                                ItemStyle-Wrap="false" 
                                ItemStyle-HorizontalAlign="Center">
                                <ItemTemplate>
                                    <asp:Button ID="recdevgvEditButton" runat="server" 
                                        CausesValidation="True" 
                                        CommandName="Edit" 
                                        Text="Edit" 
                                        CssClass="gridActionbutton" 
                                        ValidationGroup="EditDeviceValidation">
                                    </asp:Button>
                                    &nbsp;
                                    <asp:Button ID="recdevgvDeleteButton" runat="server" 
                                        CausesValidation="False" 
                                        CommandName="Delete" 
                                        Text="Delete" 
                                        CssClass="gridActionbutton" 
                                        OnClientClick="return confirm('Are you sure you want to delete this Device Information?')">
                                    </asp:Button>
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>
                </div>
                <asp:HiddenField ID="recdevgvIsExpanded" runat="server" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

如果有人可以就如何实现嵌套网格在 PageIndexChanging 事件后保持扩展提供任何指导,我将不胜感激。

谢谢。

更新

我的嵌套网格保持打开状态,但无论我单击哪一行,它始终是第一个在 PageIndexChanging 之后打开的嵌套网格。问题是隐藏字段的每一行都有相同的 ID。使用 'alert' 方法并在后面的代码中查看 UniqueId。隐藏字段始终在第一行。 隐藏字段应该在哪里?根据我在网上找到的一些代码,它位于嵌套网格末尾的 'div' 之后和 ItemTemplate 之前。还有其他地方吗?

更新 我没有正确识别隐藏字段。我相信它位于正确的位置。 这是我的 javascript 函数:

function DivExpandCollapse(RecipientID) {
    var div = document.getElementById(RecipientID);
    var img = document.getElementById('img' + RecipientID);

    if (div.style.display == "none") {
        div.style.display = "inline";
        img.src = "Images/minus.png";
        $("#recdevgvIsExpanded").val("1");
        var hiddenName = $("#recdevgvIsExpanded").attr("name");
        alert(hiddenName + " expanded");
    }
    else {
        div.style.display = "none";
        img.src = "Images/plus.png";
         $("#recdevgvIsExpanded").val("");
    }

我需要识别与 'div' 和 'img' 关联的隐藏字段。我该怎么做?

您的网格不在 UpdatePanel 内,因此每次更改索引都会生成一个完整的 post,这意味着整个页面都会重新创建,您需要将网格放在更新面板内,还要添加一个ScriptManager,之后你需要写一个JS函数,在脚本管理器请求完成时扩展网格(听起来工作量很大,但实际上并没有)

//example
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
 function()
 {
      //here you'll expand the grid
 });

关于更新面板控件的一些文档:

https://msdn.microsoft.com/en-us/library/bb399001(v=vs.140).aspx

https://msdn.microsoft.com/en-us/library/bb386452(v=vs.140).aspx

更新面板对我不起作用。我将 PlaceHolder 与文字一起使用,这对我有帮助但导致 css 问题。

但是下面的代码解决了我的问题。

希望这对遇到更新面板不起作用问题的任何人有所帮助。

    $(function () {
        $("[src*=minus]").each(function () {
            $(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>");
            $(this).next().remove()
        });
    });

Aspx 代码:

<asp:GridView ID="gv_Parent" AutoGenerateColumns="False" 
DataKeyNames="Id" Font-Size="12px" Width="100%" runat="server"  
AllowPaging="true" PageSize="10" OnPageIndexChanging="OnPageIndexChanging">

<Columns>

<asp:ImageButton ID="imgShow" runat="server" OnClick="Show_Hide_ChildGrid" 
ImageUrl="../../../assets/img/plus.png" CommandArgument="Show" />

<asp:Panel ID="pnlOrders" runat="server" Visible="false" Style="position: 
relative">

<div id="divgvTargetInfo" runat="server"  class="table-responsive">

<asp:GridView ID="gvChild" AutoGenerateColumns="False" 
DataKeyNames="Id"  runat="server" 
OnPageIndexChanging="OnTargetPageIndexChanging" AllowPaging="true" 
pagesize="10">

<Columns>


</columns>
</asp:GridView>  --closing Child Grid
</asp:Panel>
</columns>
</asp:GridView>  --closing Parent Grid

隐藏代码:

 protected void Show_Hide_ChildGrid(object sender, EventArgs e)
  {
  ImageButton imgShowHide = (sender as ImageButton);
  GridViewRow row = (imgShowHide.NamingContainer as GridViewRow);
  if (imgShowHide.CommandArgument == "Show")
    {

      row.FindControl("pnlOrders").Visible = true;
       mgShowHide.CommandArgument = "Hide";
imgShowHide.ImageUrl = "../../../assets/img/minus.png";
GridView gvwChild = row.FindControl("gvChild") as GridView;

BindChildGrid(Convert.ToInt32(gv_Parent.DataKeys[row.RowIndex].Value), 
gvwChild);

 }
else
 {
 row.FindControl("pnlOrders").Visible = true;
 imgShowHide.CommandArgument = "Hide";
 imgShowHide.ImageUrl = "../../../assets/img/minus.png";

GridView gvwChild = row.FindControl("gvChild") as GridView;

BindchildGrid(Convert.ToInt32(gv_Parent.DataKeys[row.RowIndex].Value), 
gvwChild);
 }
 }
else
{
row.FindControl("pnlOrders").Visible = false;
mgShowHide.CommandArgument = "Show";
mgShowHide.ImageUrl = "../../../assets/img/plus.png";
}
}
protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{

    gv_Parent.PageIndex = e.NewPageIndex;
    this.BindGVTSPBA();
}

protected void OnTargetPageIndexChanging(object sender, 
GridViewPageEventArgs e)
{
GridViewRow gvRowParent = (((GridView)sender)).DataItemContainer as 
GridViewRow;

GridView gvwChild = ((GridView)sender);
gvwChild.PageIndex = e.NewPageIndex;
BindChildGrid
(Convert.ToInt32(gv_Parent.DataKeys[gvRowParent.RowIndex].Value), 
gvwChild);
}