用GridView编辑更新独立的单元格。

本文介绍如何实现在ASP.NET中仅编辑GridView的单个单元格而非整行,包括使用ButtonField触发点击事件、在RowDataBound事件中设置单元格属性、RowCommand事件中的编辑状态切换及数据更新等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在asp.net 中, GridView允许你通过EditIndex属性来修改数据的一行,同样也必须进行整行更新。
你可能不想对整行进行更新,并且常规更新是利用EditItemTemplate,在它内部放上编辑状态所要显示的控件;而事实上,你可能只对其中一个单元格感兴趣,比如用上DropDownList来进行单元格筛选,而常规必须整行成编辑状态,那怎样才能直接只让一个独立的单元格成编辑状态呢?那就是本篇文章所要做的事情。
编辑独立的单元格
Screenshot - EditGridviewCells1.jpg
本篇提供的源代码中, GridView的第一列是CommandName为SingleClick的asp:ButtonField的控件,并且它的Visible置false.

这控件是为了点击GridView的某个单元格而触发点击事件:

< Columns >
    
< asp:ButtonField Text = " SingleClick "  CommandName = " SingleClick "  Visible = " False "  />
</ Columns >


而在其他的列中,利用ItemTemplate,在其中都有一个可见的Label控件,和不可见的TextBox或者DropdownList控件。

为了方便起见,我将叫这个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 >


想法是这样的,刚开始 GridView处于显示状态(也就是“非编辑状态”),当某一个单元格被点击的时候,它把Label控件置不可见而编辑控件TextBox或者DropdownList置肯见,而EditItemTemplate不需要用到。
GridView的RowDataBound的事件内对每一行中的每个单元格进行遍历,让其拥有点击触发事件的能力。

给每个单元的列索引定义上一些属性参数,如onclickstyle等等。

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;";
        }

    }

}


GridViewRowCommand事件,命令参数和事件参数被重新检索,它带给我们选择某一单元格所在的行索引和列索引。

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()");
}


在这个例子中, GridView的RowUpdating先检查每个单元格,看是否处于编辑模式下。如果处于编辑模式的单元格被找到,那么数据更新将被执行。

在第一个例子中,一些样本数据绑定到一个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)
    
{
       
// 更新数据
    }

}


为了确保RowUpdatingGridView在未选中行状态下也能够被调用,例如我在编辑模式下编辑文本框点击了“Enter”键,页面整页回发,这样确保任何数据的改变被保存。

if  ( this .GridView1.SelectedIndex  >  - 1 )
{
    
this.GridView1.UpdateRow(this.GridView1.SelectedIndex, false);
}


注册回发或回调数据以进行验证
创建在RowDataBound的自定义事件必须在页面中被注册。

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);
}

 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值