Viewstate 列表在 GridView 中单击行编辑时丢失数据

Viewstate list loses data on click row edit in GridView

我不熟悉在 asp Web 表单中使用 Viewstate。我有一个用于显示 Gridview 的描述下拉菜单。

但是,当我单击编辑行按钮时,Gridview 会清除所有数据。来自:

对此:

我的代码是:

public partial class Default : System.Web.UI.Page
    {
        private List<PRAssembly> assemblyPR = null;

......

protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                SBOConnection.Connect();            

                if (Request.QueryString["message"] == "success")
                    AlertSuccess.Visible = true;
            }
        }

   private void bindPRGridView()
        { 
            // Create Data Table
            DataTable dt = new DataTable();
            dt.Columns.Add("LineNum", typeof(int));
            dt.Columns.Add("ItemCode", typeof(string));
            dt.Columns.Add("ItemDescription", typeof(string));
            dt.Columns.Add("Quantity", typeof(int));          

            if (assemblyPR != null)
            {     
                foreach (var item in assemblyPR)
                {
                    dt.Rows.Add(item.LineNum, item.ItemCode, item.ItemDesc, item.Quantity);
                }

                pRGridView.DataSource = dt;
                pRGridView.DataBind();

                if (pRGridView.Rows.Count > 0)
                {
                    pRGridView.UseAccessibleHeader = true;
                    pRGridView.HeaderRow.TableSection = TableRowSection.TableHeader;
                }

                pRGridView.Columns[4].Visible = true;
            }
            else
            {
                dt.Rows.Add(dt.NewRow());
                pRGridView.DataSource = dt;
                pRGridView.DataBind();

                pRGridView.Columns[4].Visible = false;

                foreach (GridViewRow row in pRGridView.Rows)
                {
                    if (row.RowType == DataControlRowType.DataRow)
                    {
                        LinkButton lb = ((LinkButton)row.FindControl("lnkRemove"));
                        lb.Visible = false;
                    }
                }
            }
        }

 protected void AddRowPurchaseRequisition(object sender, EventArgs e)
        {          
            string itemCode = ((DropDownList)pRGridView.FooterRow.FindControl("ddlItemCode")).SelectedValue;
            string itemDesc = ((DropDownList)pRGridView.FooterRow.FindControl("ddlItemDescription")).SelectedValue;
            int quantity = Int32.Parse(((TextBox)pRGridView.FooterRow.FindControl("txtQuantity")).Text);

            assemblyPR = ViewState["PRList"] as List<PRAssembly>;

            if (assemblyPR == null)
            {
                assemblyPR = new List<PRAssembly>();
                ViewState["PRList"] = assemblyPR;
            }

            // Transform data to PRAssembly Class object
            assemblyPR.Add(new PRAssembly
            {               
                ItemCode = itemCode,
                ItemDesc = itemDesc,
                Quantity = quantity
            });

            // Rebind Grid view
            bindPRGridView();
        }

 protected void pRGridView_RowEditing(object sender, GridViewEditEventArgs e)
        {      
            pRGridView.EditIndex = e.NewEditIndex;
            bindPRGridView();
        }

单击编辑按钮后,我注意到在重新绑定gridview 时assemblyPR 为空。如何在不丢失数据的情况下进行编辑?

下面是一些 Gridview 标记

<asp:GridView ID="pRGridView"
                        runat="server"
                        AutoGenerateColumns="False"
                        AllowPaging="True"
                        AllowSorting="True"
                        ShowFooter="True"
                        OnRowEditing="pRGridView_RowEditing"
                        OnRowUpdating="pRGridView_RowUpdating"
                        OnPageIndexChanging="pRGridView_PageIndexChanging"
                        OnRowCancelingEdit="pRGridView_RowCancelingEdit"
                        PagerStyle-CssClass="bs-pagination"
                        ShowHeaderWhenEmpty="True"
                        EmptyDataText="No Records Found"
                        CssClass="table table-striped table-bordered table-hover table-condensed">
                        <Columns>
                            <asp:TemplateField ItemStyle-Width="30px" HeaderText="#">
                                <ItemTemplate>
                                    <%# Container.DataItemIndex + 1 %>
                                </ItemTemplate>
                                <%-- <FooterTemplate>
                                    <%# pRGridView.Rows.Count %>
                                </FooterTemplate>--%>
                            </asp:TemplateField>
                            <asp:TemplateField ItemStyle-Width="120px" HeaderText="Item No.">
                                <ItemTemplate>
                                    <asp:Label ID="lblItemCode" runat="server"
                                        Text='<%# Bind("ItemCode")%>'></asp:Label>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <asp:DropDownList ID="ddlItemCode" runat="server"
                                        AutoPostBack="True"
                                        SelectMethod="GetItemCodes"
                                        AppendDataBoundItems="True"
                                        OnSelectedIndexChanged="ddlItemCode_SelectedIndexChanged"
                                        Width="120px"
                                        DataTextField="Value" DataValueField="Key">
                                        <asp:ListItem Value="-1" Text="Select"></asp:ListItem>
                                    </asp:DropDownList>
                                    <asp:RequiredFieldValidator runat="server" ControlToValidate="ddlItemCode" Display="Dynamic" ValidationGroup="Edit"
                                        CssClass="text-danger" ErrorMessage="The Item Code field is required." />
                                </EditItemTemplate>
                                <FooterTemplate>
                                    <asp:DropDownList ID="ddlItemCode" runat="server"
                                        AutoPostBack="True"
                                        SelectMethod="GetItemCodes"
                                        AppendDataBoundItems="True"
                                        OnSelectedIndexChanged="ddlItemCode_SelectedIndexChanged"
                                        Width="120px"
                                        DataTextField="Value" DataValueField="Key">
                                        <asp:ListItem Value="-1" Text="Select"></asp:ListItem>
                                    </asp:DropDownList>
                                    <asp:RequiredFieldValidator runat="server" ControlToValidate="ddlItemCode" Display="Dynamic" ValidationGroup="Insert"
                                        CssClass="text-danger" InitialValue="-1" ErrorMessage="The Item Code field is required." />
                                </FooterTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField ItemStyle-Width="400px" HeaderText="Item Description">
                                <ItemTemplate>
                                    <asp:Label ID="lblItemDescription" runat="server" Width="120px"
                                        Text='<%# Bind("ItemDescription")%>'></asp:Label>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <asp:DropDownList ID="ddlItemDescription" runat="server"
                                        AutoPostBack="True"
                                        SelectMethod="GetItemDescriptions"
                                        AppendDataBoundItems="True"
                                        OnSelectedIndexChanged="ddlItemDescription_SelectedIndexChanged"
                                        Width="400px"
                                        DataTextField="Value" DataValueField="Value">
                                        <asp:ListItem Value="-1" Text="Select"></asp:ListItem>
                                    </asp:DropDownList>
                                    <asp:RequiredFieldValidator runat="server" ControlToValidate="ddlItemDescription" Display="Dynamic" ValidationGroup="Edit"
                                        CssClass="text-danger" ErrorMessage="The Item Description field is required." />
                                </EditItemTemplate>
                                <FooterTemplate>
                                    <asp:DropDownList ID="ddlItemDescription" runat="server"
                                        AutoPostBack="True"
                                        SelectMethod="GetItemDescriptions"
                                        AppendDataBoundItems="True"
                                        OnSelectedIndexChanged="ddlItemDescription_SelectedIndexChanged"
                                        Width="400px"
                                        DataTextField="Value" DataValueField="Value">
                                        <asp:ListItem Value="-1" Text="Select"></asp:ListItem>
                                    </asp:DropDownList>
                                    <asp:RequiredFieldValidator runat="server" ControlToValidate="ddlItemDescription" Display="Dynamic" ValidationGroup="Insert"
                                        CssClass="text-danger" InitialValue="-1" ErrorMessage="The Item Description field is required." />
                                </FooterTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField ItemStyle-Width="120px" HeaderText="Required Qty.">
                                <ItemTemplate>
                                    <asp:Label ID="lblAmount" runat="server"
                                        Text='<%# Bind("Quantity")%>'></asp:Label>
                                </ItemTemplate>
                                <EditItemTemplate>
                                    <asp:TextBox ID="txtQuantity" runat="server" Width="100px"
                                        Text='<%# Bind("Quantity")%>'></asp:TextBox>
                                    <asp:RequiredFieldValidator runat="server" ControlToValidate="txtQuantity" Display="Dynamic" ValidationGroup="Edit"
                                        CssClass="text-danger" ErrorMessage="The Quantity field is required." />
                                    <asp:RegularExpressionValidator ControlToValidate="txtQuantity" runat="server" CssClass="text-danger" Display="Dynamic"
                                        ErrorMessage="Only numbers allowed." ValidationExpression="^[0-9]{0,6}(\.[0-9]{1,2})?$"
                                        ValidationGroup="Edit"></asp:RegularExpressionValidator>
                                </EditItemTemplate>
                                <FooterTemplate>
                                    <asp:TextBox ID="txtQuantity" runat="server" Width="100px"></asp:TextBox>
                                    <asp:RequiredFieldValidator runat="server" ControlToValidate="txtQuantity" Display="Dynamic" ValidationGroup="Insert"
                                        CssClass="text-danger" ErrorMessage="The Quantity field is required." />
                                    <asp:RegularExpressionValidator ControlToValidate="txtQuantity" runat="server" CssClass="text-danger" Display="Dynamic"
                                        ErrorMessage="Only numbers allowed." ValidationExpression="^[0-9]{0,6}(\.[0-9]{1,2})?$"
                                        ValidationGroup="Insert"></asp:RegularExpressionValidator>
                                </FooterTemplate>
                            </asp:TemplateField>
                            <asp:CommandField ShowEditButton="True" ValidationGroup="Edit" />
                            <asp:TemplateField>
                                <ItemTemplate>
                                    <asp:LinkButton ID="lnkRemove" runat="server"
                                        CommandArgument='<%# Bind("LineNum")%>'
                                        OnClientClick="return confirm('Are you sure you want to delete this row?')"
                                        Text="Delete" OnClick="DeleteRowPurchaseRequisition"></asp:LinkButton>
                                </ItemTemplate>
                                <FooterTemplate>
                                    <asp:Button ID="btnAdd" runat="server" Text="Add" ValidationGroup="Insert" CssClass="btn btn-primary btn-sm"
                                        OnClick="AddRowPurchaseRequisition" />
                                </FooterTemplate>
                            </asp:TemplateField>
                            </Columns>
                        </asp:GridView>
  </ContentTemplate>
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="pRGridView" />
                </Triggers>

编辑后,assemblyPR 变为 null,因为您在调用 bindPRGridView() 之前没有为其赋值。一种修复方法是在 pRGridView_RowEditing:

中添加一行
protected void pRGridView_RowEditing(object sender, GridViewEditEventArgs e)
{
    pRGridView.EditIndex = e.NewEditIndex;
    assemblyPR = ViewState["PRList"] as List<PRAssembly>;
    bindPRGridView();
}