使用DataGrid隐藏列插入新行






3.64/5 (14投票s)
2005 年 6 月 23 日
5分钟阅读

188027

2502
使用 DataGrid 轻松输入新数据值,其中包含一个隐藏行。
引言
这是一个非常简单的示例,演示了如何在 ASP.NET 页面中使用 DataGrid
控件,通过在网格的第一个行位置创建一个隐藏的空行来输入新数据。这具有非常简洁的外观,并避免了为输入单个字段的数据而设计新页面。
入门
首先,在 Visual Studio 中创建一个带有 DataGrid
和用于插入新行的按钮的网页。右键单击网格并使用 AutoFormat 设计外观,或者直接进入 Property Builder 并按您喜欢的方式格式化属性。在 Property Builder 中,选择 Columns,然后展开 Available Columns 下的 Button Column。现在,通过突出显示该选择并按“>”按钮添加 Edit/Update/Cancel 按钮。底部的 Edit、Update 和 Cancel 文本应注意。如果您更改了此文本,您将需要知道这一点以便在代码中使用。保存网格属性并关闭 Property Builder。
创建事件
添加 Edit 链接按钮后,必须为其分配关联的事件。右键单击网格并打开 Properties 窗口。单击顶部看起来像闪电的 Events 按钮。您需要为 Edit、Update 和 Cancel 命令以及 ItemCreated
事件添加事件。通过单击事件右侧的空白框并键入名称来为每个事件输入一个方法名。我使用了这些名称:OnGridItemEdit
、OnGridItemUpdate
、OnGridItemCancel
和 OnGridItemCreated
。每次输入名称时,您都会被带到代码隐藏文件,并且每次都需要返回到页面显示。
完成编辑事件后,双击您添加的 Insert 按钮,将自动添加一个用于按钮点击事件的新方法,准备好进行编码。
编写代码
现在可以输入代码来处理创建隐藏的“虚拟”行以进行插入,以及处理行创建和编辑时的所有事件。
为了模拟某种数据源,我直接使用了帮助主题中的 CreateDataSource
方法。这只是一个简单的 DataTable
创建,它用随机数据填充了一些行。我对代码进行了一些修改,以便在位置 0 添加一个空行。
ICollection CreateDataSource()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));
dt.Columns.Add(new DataColumn("StringValue", typeof(string)));
dt.Columns.Add(new DataColumn("CurrencyValue", typeof(double)));
for (int i = 0; i < 9; i++)
{
dr = dt.NewRow();
if (i == 0)
{
/* first row will be hidden insert row */
dr[0] = -1;
dr[1] = "";
dr[2] = -1;
}
else
{
dr[0] = i;
dr[1] = "Item " + i.ToString();
dr[2] = 1.23 * (i + 1);
}
dt.Rows.Add(dr);
}
DataView dv = new DataView(dt);
return dv;
}
接下来,我在初始的 Page_Load
中将数据源绑定到网格。
private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
/* Load this data only once. */
DataGrid1.DataSource= CreateDataSource();
DataGrid1.DataBind();
}
}
现在,来看事件。
要查看的第一个事件处理程序是 OnGridItemCreated
方法,当 DataGrid
中的每一行被创建时都会调用此方法。这就是我们想要隐藏数据源中的第一行(即虚拟行)的地方。当项目未被编辑时,这可以通过将位置 0 的所有列的 Visible
属性设置为 false
来实现。如果此行正在被编辑,我们将知道这一点,因为第一个控件的文本将更改为 Update 文本。
还请注意,对于现有项目,我不想允许编辑第一个数据列。在许多实际应用程序中,这通常是主键,因此这会很有用。
private void OnGridItemCreated(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if ( e.Item.ItemIndex == 0 )
{
System.Web.UI.WebControls.LinkButton lb =
( System.Web.UI.WebControls.LinkButton )e.Item.Cells[0].Controls[0];
if ( lb.Text == "Edit" )
{
/* If this is row 0 and not inserting, hide the row */
lb.Text = "";
e.Item.Cells[0].Visible = false;
e.Item.Cells[1].Visible = false;
e.Item.Cells[2].Visible = false;
e.Item.Cells[3].Visible = false;
}
else if ( lb.Text == "Update" )
{
/* If inserting, make row visible */
lb.Text = "Insert";
e.Item.Cells[0].Visible = true;
e.Item.Cells[1].Visible = true;
e.Item.Cells[2].Visible = true;
e.Item.Cells[3].Visible = true;
}
}
else if (e.Item.ItemIndex > 0)
{
/* Make first data column read-only for existing items */
System.Web.UI.WebControls.LinkButton lb =
( System.Web.UI.WebControls.LinkButton )e.Item.Cells[0].Controls[0];
if (lb.Text == "Update")
{
if (e.Item.Cells[1].Controls.Count > 0)
((TextBox)e.Item.Cells[1].Controls[0]).Enabled = false;
}
}
}
下一个要查看的事件处理程序是按下 Insert 按钮时调用的方法。此事件将指示隐藏的行将被编辑,并且必须可见。这可以通过将 DataGrid
的 EditItemIndex
设置为 0 来实现,这意味着行 0 现在正在被编辑。DataGrid
将把位置 0 行中的链接按钮的“Edit”文本更改为“Update Cancel”。这反过来会指示 ItemCreated
事件现在显示该行。请注意,在此示例中,数据源会被重新绑定,Insert 按钮会被禁用。
private void btnInsert_Click(object sender, System.EventArgs e)
{
/* The hidden row at position 0 will be used to enter data */
DataGrid1.EditItemIndex = 0;
DataGrid1.DataSource= CreateDataSource();
DataGrid1.DataBind();
btnInsert.Enabled = false;
}
Edit 和 Cancel 事件与 Insert 事件非常相似,只是设置或移除要编辑的行。
private void OnGridItemCancel(object source,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = -1;
DataGrid1.DataSource= CreateDataSource();
DataGrid1.DataBind();
btnInsert.Enabled = true;
}
private void OnGridItemEdit(object source,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = e.Item.ItemIndex;
DataGrid1.DataSource= CreateDataSource();
DataGrid1.DataBind();
btnInsert.Enabled = false;
}
最后,Update 事件被编码以接受新行或已更改的行。我没有深入介绍如何从网格行中提取数据并实际更新网格的详细信息。由于我没有真正的数据源,因此没有什么可以更新的,而且我不想使这个示例的原始意图(展示如何使用隐藏行进行插入)复杂化。因此,Update 事件只是一个待填充的模板,它只提供一个漂亮的 Message Box 来告知您发生了什么。请注意,一旦 EditItemIndex
被清除,按钮就会再次启用。
private void OnGridItemUpdate(object source,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
String scriptString = "";
if (e.Item.ItemIndex == 0)
{
/* code here to add new item */
scriptString = "<script language=JavaScript> alert('New Item Added!')";
}
else
{
/* code here to update existing item */
scriptString = "<script language=JavaScript> alert('Item Updated!')";
}
scriptString += "<";
scriptString += "/";
scriptString += "script>";
if(!this.IsClientScriptBlockRegistered("clientScript"))
this.RegisterClientScriptBlock("clientScript", scriptString);
DataGrid1.EditItemIndex = -1;
DataGrid1.DataSource= CreateDataSource();
DataGrid1.DataBind();
btnInsert.Enabled = true;
}
几点说明
这个示例展示了一种非常简单的方法,可以使用干净的界面和简单的编码来将新数据插入到 DataGrid
中。在使用这种功能时,您需要特别注意以下几点:
- 您需要知道您的数据源代表多少列以及它们的类型。当使用自动列创建时,这可能会很棘手。您可能会发现某些类型在虚拟行中需要一个值,因为它是一个非空字段或其他什么。
- 如果您想要可排序的列,您必须确保虚拟行中的值始终位于第 0 行。这可以通过在排序后添加虚拟行来完成。
我希望您觉得这个示例和我一样有用。