如何删除动态Gridview中的行?

时间:2014-01-12 13:26:26

标签: c# asp.net gridview

作为一个测试项目,我在ASP.NET中使用一个简单的库存系统。在一个页面中,我必须创建用于输入购买详细信息的页面!我使用动态gridview来简化数据输入。我使用了this tutorial this article但我在删除gridview中的行时遇到了问题。我见过这个similar post,但没有用。

aspx代码如下 -

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
    Purchase Management</h2>
<asp:GridView ID="PurchaseMgmtGridView" runat="server" ShowFooter="True" AutoGenerateColumns="False"
    CellPadding="4" ForeColor="#333333" GridLines="None" OnRowDeleting="PurchaseMgmtGridView_RowDeleting">
    <Columns>
        <asp:TemplateField HeaderText="Item">
            <ItemTemplate>
                <asp:DropDownList ID="ItemDropDownList" runat="server" AppendDataBoundItems="true"> 
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="ItemUnit">
            <ItemTemplate>
                <asp:DropDownList ID="ItemUnitDropDownList" runat="server" AppendDataBoundItems="true">
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Rate">
            <ItemTemplate>
                <asp:TextBox ID="RateTextBox" runat="server">
                </asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Qty.">
            <ItemTemplate>
                <asp:TextBox ID="QtyTextBox" runat="server">
                </asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Total">
            <ItemTemplate>
                <asp:Label ID="TotalLabel" runat="server">
                </asp:Label>
            </ItemTemplate>
            <FooterStyle HorizontalAlign="Right" />
            <FooterTemplate>
                <asp:Button ID="ButtonAddNewRow" runat="server" Text=" + " OnClick="ButtonAddNewRow_Click" />
            </FooterTemplate>
        </asp:TemplateField>
        <asp:CommandField ShowDeleteButton="True" />
    </Columns>
</asp:GridView>
</asp:Content>

这是aspx.cs代码 -

namespace SmoothInventoryWeb.Pages.ItemManagment
{
   public class Item
    {
        public string Id { get; set; }
        public string Name{get; set;}
    }

    public class ItemUnit
    {
        public string Id { get; set; }
        public string Name{get; set;}
    }
    public partial class PurchaseManagementPage : System.Web.UI.Page
    {
      public List<Item> GetItemList()
    {
        List<Item> itemList = new List<Item>();

        itemList.Add(new Item { Id = "1", Name = "Carpet" });
        itemList.Add(new Item { Id = "2", Name = "Pasmina Muffler" });
        itemList.Add(new Item { Id = "3", Name = "Large Carpet" });
        return itemList;
    }

    public List<ItemUnit> GetItemUnitList()
    {
        List<ItemUnit> itemUnitList = new List<ItemUnit>();

        itemUnitList.Add(new ItemUnit { Id = "1", Name = "Pieces" });
        itemUnitList.Add(new ItemUnit { Id = "2", Name = "Dorzen" });
        itemUnitList.Add(new ItemUnit { Id = "3", Name = "Gross" });
        return itemUnitList;
    }

    List<Item> itemList = new List<Item>();
    List<ItemUnit> itemUnitList = new List<ItemUnit>();
    protected void Page_Load(object sender, EventArgs e)
    {
        this.itemList = GetItemList();
        this.itemUnitList = GetItemUnitList();
        if (!Page.IsPostBack)
            addFirstRowInGridView();
    }

    private void FillItemDropDownList(DropDownList dropDownList)
    {
        if (dropDownList == null)
            return;
        foreach (Item item in itemList)
        {
            dropDownList.Items.Add(new ListItem(item.Name.ToString(), item.Id.ToString()));
        }
    }

    private void FillItemUnitDropDownList(DropDownList dropDownList)
    {
        if (dropDownList == null)
            return;
        foreach (ItemUnit itemUnit in itemUnitList)
        {
            dropDownList.Items.Add(new ListItem(itemUnit.Name.ToString(), itemUnit.Id.ToString()));
        }
    }


    protected void ButtonAddNewRow_Click(object sender, EventArgs e)
    {
        AddNewRow();
    }

    private void addFirstRowInGridView()
    {
        DataTable dataTable = new DataTable();
        dataTable.Columns.Add(new DataColumn("Item", typeof(string)));
        dataTable.Columns.Add(new DataColumn("ItemUnit", typeof(string)));
        dataTable.Columns.Add(new DataColumn("Rate", typeof(string)));
        dataTable.Columns.Add(new DataColumn("Qty", typeof(string)));
        dataTable.Columns.Add(new DataColumn("Total", typeof(string)));
        DataRow dataRow = dataTable.NewRow();


        dataRow["Item"] = string.Empty;
        dataRow["ItemUnit"] = string.Empty;
        dataRow["Rate"] = string.Empty;
        dataRow["Qty"] = string.Empty;
        dataRow["Total"] = string.Empty;
        dataTable.Rows.Add(dataRow);
        ViewState["CurrentTable"] = dataTable;

        PurchaseMgmtGridView.DataSource = dataTable;
        PurchaseMgmtGridView.DataBind();

        DropDownList itemDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[0].Cells[0].FindControl("ItemDropDownList");
        DropDownList itemUnitDropDownList =
          (DropDownList)PurchaseMgmtGridView.Rows[0].Cells[1].FindControl("ItemUnitDropDownList");
        FillItemDropDownList(itemDropDownList);
        FillItemUnitDropDownList(itemUnitDropDownList);


    }

    private void AddNewRow()
    {
        int rowIndex = 0;

        if (ViewState["CurrentTable"] != null)
        {
            DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
            DataRow drCurrentRow = null;
            if (dtCurrentTable.Rows.Count > 0)
            {
                for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
                {
                    DropDownList itemDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");
                    DropDownList itemUnitDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[1].FindControl("ItemUnitDropDownList");
                    TextBox rateTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[2].FindControl("RateTextBox");
                    TextBox qtyTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[3].FindControl("QtyTextBox");
                    Label totalLabel =
                      (Label)PurchaseMgmtGridView.Rows[rowIndex].Cells[4].FindControl("TotalLabel");

                    drCurrentRow = dtCurrentTable.NewRow();


                    dtCurrentTable.Rows[i - 1]["Item"] = itemDropDownList.SelectedItem.ToString();
                    dtCurrentTable.Rows[i - 1]["ItemUnit"] = itemUnitDropDownList.SelectedItem.ToString();
                    dtCurrentTable.Rows[i - 1]["Rate"] = rateTextBox.Text;
                    dtCurrentTable.Rows[i - 1]["Qty"] = qtyTextBox.Text;
                    dtCurrentTable.Rows[i - 1]["Total"] = totalLabel.Text;

                }
                dtCurrentTable.Rows.Add(drCurrentRow);
                ViewState["CurrentTable"] = dtCurrentTable;

                PurchaseMgmtGridView.DataSource = dtCurrentTable;
                PurchaseMgmtGridView.DataBind();
            }
        }
        else
        {
            Response.Write("ViewState is null");
        }
        SetPreviousData();
    }

    private void SetPreviousData()
    {
        int rowIndex = 0;
        if (ViewState["CurrentTable"] != null)
        {
            DataTable dt = (DataTable)ViewState["CurrentTable"];
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    DropDownList itemDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");
                    DropDownList itemUnitDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[1].FindControl("ItemUnitDropDownList");
                    TextBox rateTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[2].FindControl("RateTextBox");
                    TextBox qtyTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[3].FindControl("QtyTextBox");
                    Label totalLabel =
                      (Label)PurchaseMgmtGridView.Rows[rowIndex].Cells[4].FindControl("TotalLabel");

                    FillItemDropDownList(itemDropDownList);
                    FillItemUnitDropDownList(itemUnitDropDownList);


                    if (i < dt.Rows.Count - 1)
                    {
                        //itemDropDownList.SelectedValue = dt.Rows[i]["Item"].ToString();
                        //itemUnitDropDownList.SelectedValue = dt.Rows[i]["ItemUnit"].ToString();
                        itemDropDownList.ClearSelection();
                        itemDropDownList.Items.FindByText(dt.Rows[i]["Item"].ToString()).Selected = true;
                        itemUnitDropDownList.ClearSelection();
                        itemUnitDropDownList.Items.FindByText(dt.Rows[i]["ItemUnit"].ToString()).Selected = true;
                    }

                    rateTextBox.Text = dt.Rows[i]["Rate"].ToString();
                    qtyTextBox.Text = dt.Rows[i]["Qty"].ToString();
                    totalLabel.Text = dt.Rows[i]["Total"].ToString();
                    rowIndex++;
                }
            }
        }
    }

    protected void PurchaseMgmtGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        SetRowData();
        if (ViewState["CurrentTable"] != null)
        {
            DataTable dt = (DataTable)ViewState["CurrentTable"];
            DataRow drCurrentRow = null;
            int rowIndex = Convert.ToInt32(e.RowIndex);
            if (dt.Rows.Count > 1)
            {
                dt.Rows.Remove(dt.Rows[rowIndex]);
                drCurrentRow = dt.NewRow();
                ViewState["CurrentTable"] = dt;
                PurchaseMgmtGridView.DataSource = dt;
                PurchaseMgmtGridView.DataBind();

                for (int i = 0; i < PurchaseMgmtGridView.Rows.Count - 1; i++)
                {
                    PurchaseMgmtGridView.Rows[i].Cells[0].Text = Convert.ToString(i + 1);
                }
                SetPreviousData();
            }
        }
    }
    private void SetRowData()
    {
        int rowIndex = 0;

        if (ViewState["CurrentTable"] != null)
        {
            DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
            DataRow drCurrentRow = null;
            if (dtCurrentTable.Rows.Count > 0)
            {
                for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
                {
                    DropDownList itemUnitDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[1].FindControl("ItemUnitDropDownList");
                    DropDownList itemDropDownList =
                       (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");

                    TextBox rateTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[2].FindControl("RateTextBox");
                    TextBox qtyTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[rowIndex].Cells[3].FindControl("QtyTextBox");
                    Label totalLabel =
                      (Label)PurchaseMgmtGridView.Rows[rowIndex].Cells[4].FindControl("TotalLabel");
                    drCurrentRow = dtCurrentTable.NewRow();
                    //drCurrentRow["RowNumber"] = i + 1;
                    dtCurrentTable.Rows[i - 1]["Item"] = itemDropDownList.SelectedItem.ToString();
                    dtCurrentTable.Rows[i - 1]["ItemUnit"] = itemUnitDropDownList.SelectedItem.ToString();
                    dtCurrentTable.Rows[i - 1]["Rate"] = rateTextBox.Text;
                    dtCurrentTable.Rows[i - 1]["Qty"] = qtyTextBox.Text;
                    dtCurrentTable.Rows[i - 1]["Total"] = totalLabel.Text;
                    rowIndex++;
                }

                ViewState["CurrentTable"] = dtCurrentTable;

            }
        }
        else
        {
            Response.Write("ViewState is null");
        }
     }
   }
}

这些代码会产生类似这样的结果

enter image description here

但是,一旦我开始删除其中一行,它就会给我这个例外 -

enter image description here

从以下代码 -

中的SetPreviousData()方法抛出此异常
DropDownList itemDropDownList =  (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");

我知道哪里出错了?

P.S。 :代码更新I [提供实体列表的代码ieItem和ItemUnit]

2 个答案:

答案 0 :(得分:2)

看起来它实际上是删除GridView中的行而不是其他问题。

首先,需要注意两件事 - 我无法编译,因为我没有ItemItemUnit的定义,所以我通过阅读代码来做到这一点。 其次,我还没喝完咖啡! (更新:我的咖啡已经完成!)

itemDropDownList中对SetPreviousData()的引用似乎为null,因此请查看原因。使用foreach循环来迭代遍历DataTable的行可能更容易,以避免基于0的索引和count-1比较等的任何问题。(更新:它仍然会更容易,但它不会导致问题。 )

另外,不确定是否要执行此操作,但是获取ItemDropDownList的FindControl语句使用的rowIndex始终等于i。 (更新:再次,可以帮助只是清理代码,但这不是一个要求。)

首先弄清楚崩溃时i是什么,看看是否符合预期,并找出FindControl语句无法正常工作的原因。如果它为0,则可能是尝试读取标题行或不存在该Dropdown的内容。

抱歉,我不能给你一个明确的解决方案,但希望这会有所帮助。

<强>解决方案: 获得完整代码后,更容易看到发生了什么。基本上,PurchaseMgmtGridView_RowDeleting方法是从GridView中删除DropdownList,然后SetPreviousData()试图读取不存在的内容。 FindControl中的SetPreviousData语句返回NULL,如错误消息中所示,但不是我之前推测的原因。

PurchaseMgmtGridView_RowDeleting方法中移除违规行,您将全部设置完毕。

  protected void PurchaseMgmtGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            SetRowData();
            if (ViewState["CurrentTable"] != null)
            {
                DataTable dt = (DataTable)ViewState["CurrentTable"];
                DataRow drCurrentRow = null;
                int rowIndex = Convert.ToInt32(e.RowIndex);
                if (dt.Rows.Count > 1)
                {
                    dt.Rows.Remove(dt.Rows[rowIndex]);
                    drCurrentRow = dt.NewRow();
                    ViewState["CurrentTable"] = dt;
                    PurchaseMgmtGridView.DataSource = dt;
                    PurchaseMgmtGridView.DataBind();

                    // Delete this
                    //for (int i = 0; i < PurchaseMgmtGridView.Rows.Count - 1; i++)
                    //{
                    //    PurchaseMgmtGridView.Rows[i].Cells[0].Text = Convert.ToString(i + 1);
                    //}
                    SetPreviousData();
                }
            }
        }

答案 1 :(得分:0)

我认为您尝试访问指向null的对象引用。

试试这个

 private void SetPreviousData()
    {
        if (ViewState["CurrentTable"] != null)
        {
            DataTable dt = (DataTable)ViewState["CurrentTable"];
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count-1; i++)
                {
                    DropDownList itemDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[i].Cells[0].FindControl("ItemDropDownList");
                    DropDownList itemUnitDropDownList =
                      (DropDownList)PurchaseMgmtGridView.Rows[i].Cells[1].FindControl("ItemUnitDropDownList");
                    TextBox rateTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[i].Cells[2].FindControl("RateTextBox");
                    TextBox qtyTextBox =
                      (TextBox)PurchaseMgmtGridView.Rows[i].Cells[3].FindControl("QtyTextBox");
                    Label totalLabel =
                      (Label)PurchaseMgmtGridView.Rows[i].Cells[4].FindControl("TotalLabel");

                    FillItemDropDownList(itemDropDownList);
                    FillItemUnitDropDownList(itemUnitDropDownList);


                    if (i < dt.Rows.Count - 1)
                    {
                        //itemDropDownList.SelectedValue = dt.Rows[i]["Item"].ToString();
                        //itemUnitDropDownList.SelectedValue = dt.Rows[i]["ItemUnit"].ToString();
                        itemDropDownList.ClearSelection();
                        itemDropDownList.Items.FindByText(dt.Rows[i]["Item"].ToString()).Selected = true;
                        itemUnitDropDownList.ClearSelection();
                        itemUnitDropDownList.Items.FindByText(dt.Rows[i]["ItemUnit"].ToString()).Selected = true;
                    }

                    rateTextBox.Text = dt.Rows[i]["Rate"].ToString();
                    qtyTextBox.Text = dt.Rows[i]["Qty"].ToString();
                    totalLabel.Text = dt.Rows[i]["Total"].ToString();                        
                }
            }
        }
    }

请参阅此处Null Reference Exception