本篇提供的源代码中, GridView的第一列是CommandName为SingleClick的asp:ButtonField的控件,并且它的Visible置false.
这控件是为了点击GridView的某个单元格而触发点击事件:
<
Columns
>
<
asp:ButtonField Text
=
"
SingleClick
"
CommandName
=
"
SingleClick
"
Visible
=
"
False
"
/>
</
Columns
>
为了方便起见,我将叫这个Label为“非编辑状态控件”和TextBox或者DropdownList的“编辑状态控件”。
<
asp:TemplateField HeaderText
=
"
Task
"
>
<
ItemTemplate
>

<
asp:Label ID
=
"
DescriptionLabel
"
runat
=
"
server
"
Text
=
'
<%# Eval("Description") %>
'
></
asp:Label
>
<
asp:TextBox ID
=
"
Description
"
runat
=
"
server
"
Text
=
'
<%# Eval("Description") %>
'
Width
=
"
175px
"
visible
=
"
false
"
></
asp:TextBox
>
</
ItemTemplate
>
</
asp:TemplateField
>
给每个单元的列索引定义上一些属性参数,如onclick,style等等。
protected
void
GridView1_RowDataBound(
object
sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// 得到第一个单元格的LinkButton控件
LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
// 得到客户端javascript能够引起LinkButton回发事件的脚本
string _jsSingle = ClientScript.GetPostBackClientHyperlink(
_singleClickButton, "");
// 添加事件到每个可编辑的单元格
for (int columnIndex = _firstEditCellIndex; columnIndex <
e.Row.Cells.Count; columnIndex++)
{
// 插入列索引参数
string js = _jsSingle.Insert(_jsSingle.Length - 2,
columnIndex.ToString());
// 给单元格添加javscript的onclick属性
e.Row.Cells[columnIndex].Attributes["onclick"] = js;
// 给单元格添加鼠标样式
e.Row.Cells[columnIndex].Attributes["style"] +=
"cursor:pointer;cursor:hand;";
}
}
}
在GridView的RowCommand事件,命令参数和事件参数被重新检索,它带给我们选择某一单元格所在的行索引和列索引。
int
_rowIndex
=
int
.Parse(e.CommandArgument.ToString());
int
_columnIndex
=
int
.Parse(Request.Form[
"
__EVENTARGUMENT
"
]);
被选中的单元格也必须移除点击的事件。
//
得到选中单元格的显示控件使它不可见
Control _displayControl
=
_gridView.Rows[_rowIndex].Cells[_columnIndex].Controls[
1
];
_displayControl.Visible
=
false
;
//
得到选中单元格的编辑控件是它可见
Control _editControl
=
_gridView.Rows[_rowIndex].Cells[_columnIndex].Controls[
3
];
_editControl.Visible
=
true
;
//
移除选中单元格的点击属性
_gridView.Rows[_rowIndex].Cells[_columnIndex].Attributes.Clear();
还有一些代码是在事件回发之后在编辑控件上置焦点。如果编辑控件是一个DropDownList那么它的SelectedValue属性被置上显示控件的值,如果编辑控件是一个TextBox那么它的文本被选上将准备进行编辑。
//
在选中的编辑控件上置焦点
ClientScript.RegisterStartupScript(GetType(),
"
SetFocus
"
,
"
<script>document.getElementById(
'
" + _editControl.ClientID + "
'
).focus();
</
script
>
"
);
//
如果编辑控件是dropdownlist置selectedValue为显示控件的值
if
(_editControl
is
DropDownList
&&
_displayControl
is
Label)
{
((DropDownList)_editControl).SelectedValue = (
(Label)_displayControl).Text;
}
//
如果编辑控件是TextBox文本选上准备进行编辑
if
(_editControl
is
TextBox)
{
((TextBox)_editControl).Attributes.Add("onfocus", "this.select()");
}
在第一个例子中,一些样本数据绑定到一个DataTable中存储在Session里
//
遍历GridView的列索引查找处于编辑模式下的单元格
for
(
int
i
=
1
; i
<
_gridView.Columns.Count; i
++
)
{
// Get the editing control for the cell
Control _editControl = _gridView.Rows[e.RowIndex].Cells[i].Controls[3];
if (_editControl.Visible)
{
// 更新数据
}
}
为了确保RowUpdating在GridView在未选中行状态下也能够被调用,例如我在编辑模式下编辑文本框点击了“Enter”键,页面整页回发,这样确保任何数据的改变被保存。
if
(
this
.GridView1.SelectedIndex
>
-
1
)
{
this.GridView1.UpdateRow(this.GridView1.SelectedIndex, false);
}
ClientScriptManager.RegisterForEventValuedation通过重载Render方法来调用。
protected
override
void
Render(HtmlTextWriter writer)
{
foreach (GridViewRow r in GridView1.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
for (int columnIndex = _firstEditCellIndex; columnIndex <
r.Cells.Count; columnIndex++)
{
Page.ClientScript.RegisterForEventValidation(
r.UniqueID + "$ctl00", columnIndex.ToString());
}
}
}
base.Render(writer);
}
本文介绍如何实现在ASP.NET中仅编辑GridView的单个单元格而非整行,包括使用ButtonField触发点击事件、在RowDataBound事件中设置单元格属性、RowCommand事件中的编辑状态切换及数据更新等步骤。
3579





