作为一个测试项目,我在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");
}
}
}
}
这些代码会产生类似这样的结果
但是,一旦我开始删除其中一行,它就会给我这个例外 -
从以下代码 -
中的SetPreviousData()方法抛出此异常DropDownList itemDropDownList = (DropDownList)PurchaseMgmtGridView.Rows[rowIndex].Cells[0].FindControl("ItemDropDownList");
我知道哪里出错了?
P.S。 :代码更新I [提供实体列表的代码ieItem和ItemUnit]
答案 0 :(得分:2)
看起来它实际上是删除GridView中的行而不是其他问题。
首先,需要注意两件事 - 我无法编译,因为我没有其次,我还没喝完咖啡! (更新:我的咖啡已经完成!)Item
和ItemUnit
的定义,所以我通过阅读代码来做到这一点。
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();
}
}
}
}