Gridview中RowUpdating事件e.NewValues.Add(key,value)与e.NewValues[_columnKeys[i-2]] = value的区别

   近来使用Gridview中的单元格编辑功能,参考前面的博客。发现在使用中存在着如下的注意事项

1.SqlDataSource必须包含着UpdateCommand并且要包含主键,尤其注意的是在相关联的Gridview中有DataKeyNames="EmployeeID"这个属性。

2.在gridview中自动添加的模板中有<asp:Label ID="Label1" runat="server" Text='<%# Bind("LastName") %>'>,但是必须注意bind与Eval的区别问题。不然会出现如下的问题

在RowUpdating事件中Item has already been added. Key in dictionary: 'LastName'  Key being added: 'LastName'。解决方式:bind对应着e.NewValues[_columnKeys[i-2]] = value;,而eval须对应e.NewValues.Add(key, value);

此文中再一次把相关代码附上:

代码
/* 为了方便,我们称Label为显示控件,TextBox或DropDownList为编辑控件 */
using  System;
using  System.Data;
using  System.Configuration;
using  System.Collections;
using  System.Web;
using  System.Web.Security;
using  System.Web.UI;
using  System.Web.UI.WebControls;
using  System.Web.UI.WebControls.WebParts;
using  System.Web.UI.HtmlControls;

public   partial   class  Control_EditIndividualCell : System.Web.UI.Page
{
    
private   const   int  _firstEditCellIndex  =   2 ;

    
protected   void  Page_Load( object  sender, EventArgs e)
    {
        
if  ( ! IsPostBack)
        {
            
this .GridView1.DataBind();
        }

        
if  ( this .GridView1.SelectedIndex  >   - 1 )
        {
            
//  调用GridView的UpdateRow方法
             this .GridView1.UpdateRow( this .GridView1.SelectedIndex,  false );
        }
    }

    
protected   void  GridView1_RowDataBound( object  sender, GridViewRowEventArgs e)
    {
        
if  (e.Row.RowType  ==  DataControlRowType.DataRow)
        {
            
//  从第一个单元格内获得LinkButton控件
            LinkButton _singleClickButton  =  (LinkButton)e.Row.Cells[ 0 ].Controls[ 0 ];
            
//  返回一个字符串,表示对包含目标控件的 ID 和事件参数的回发函数的 JavaScript 调用
             string  _jsSingle  =  ClientScript.GetPostBackClientHyperlink(_singleClickButton,  "" );

            
//  给每一个可编辑的单元格增加事件
             for  ( int  columnIndex  =  _firstEditCellIndex; columnIndex  <  e.Row.Cells.Count; columnIndex ++ )
            {
                
//  增加列索引作为事件参数
                 string  js  =  _jsSingle.Insert(_jsSingle.Length  -   2 , columnIndex.ToString());
                
//  给单元格增加onclick事件
                e.Row.Cells[columnIndex].Attributes[ " onclick " =  js;
                
//  给单元格增加鼠标经过时指针样式
                e.Row.Cells[columnIndex].Attributes[ " style " +=   " cursor:pointer;cursor:hand; " ;
            }
        }
    }

    
protected   void  GridView1_RowCommand( object  sender, GridViewCommandEventArgs e)
    {
        GridView _gridView 
=  (GridView)sender;

        
switch  (e.CommandName)
        {
            
case  ( " SingleClick " ):
                
//  获得行索引
                 int  _rowIndex  =   int .Parse(e.CommandArgument.ToString());
                
//  解析事件参数(在RowDataBound中增加的),从而获得被选中的列的索引
                 int  _columnIndex  =   int .Parse(Request.Form[ " __EVENTARGUMENT " ]);
                
//  设置GridView被选中的行的索引(每次回发后判断GridView1.SelectedIndex > -1则更新)
                _gridView.SelectedIndex  =  _rowIndex;
                
//  绑定
                _gridView.DataBind();

                
//  事件记录
                 this .Message.Text  +=   " 单击GridView的行的索引为: "   +  _rowIndex.ToString()
                    
+   " ;列索引为: "   +  _columnIndex  +   " <br /> " ;

                
//  获得被选中单元格的显示控件并设置其不可见
                Control _displayControl  =  _gridView.Rows[_rowIndex].Cells[_columnIndex].Controls[ 1 ];
                _displayControl.Visible 
=   false ;
                
//  获得被选中单元格的编辑控件并设置其可见
                Control _editControl  =  _gridView.Rows[_rowIndex].Cells[_columnIndex].Controls[ 3 ];
                _editControl.Visible 
=   true ;
                
//  清除被选中单元格属性以删除click事件
                _gridView.Rows[_rowIndex].Cells[_columnIndex].Attributes.Clear();

                
//  设置焦点到被选中的编辑控件
                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() " );
                }

                
break ;
        }
    }

    
///   <summary>
    
///  把值(values)从EditItemTemplate转移到NewValues集合里(使用数据源控件的话就需要这步)
    
///   </summary>
    
///   <param name="sender"></param>
    
///   <param name="e"></param>
     protected   void  GridView1_RowUpdating( object  sender, GridViewUpdateEventArgs e)
    {
        GridView _gridView 
=  (GridView)sender;
        
string  key  =   "" ;
        
string  value  =   "" ;

        
//  NewValues集合里的key
         string [] _columnKeys  =   new   string [] {  " LastName " " FirstName " " Country "  };

        
if  (e.RowIndex  >   - 1 )
        {
            
//  循环每一列
             for  ( int  i  =  _firstEditCellIndex; i  <  _gridView.Columns.Count; i ++ )
            {
                
//  获得单元格里的控件
                Control _displayControl  =  _gridView.Rows[e.RowIndex].Cells[i].Controls[ 1 ];
                Control _editControl 
=  _gridView.Rows[e.RowIndex].Cells[i].Controls[ 3 ];

                
//  获得列的key
                key  =  _columnKeys[i  -  _firstEditCellIndex];

                
//  如果单元格处于编辑模式的话,那么从编辑控件中获取值
                 if  (_editControl.Visible)
                {
                    
if  (_editControl  is  TextBox)
                    {
                        value 
=  ((TextBox)_editControl).Text;
                    }
                    
else   if  (_editControl  is  DropDownList)
                    {
                        value 
=  ((DropDownList)_editControl).SelectedValue;
                    }

                    
//  增加key/value对到NewValues集合
                    e.NewValues.Add(key, value);
                }
                
//  否则从显示控件中获取值
                 else
                {
                    value 
=  ((Label)_displayControl).Text.ToString();

                    
//  增加key/value对到NewValues集合
                    e.NewValues.Add(key, value);
                }
            }
        }
    }

    
//  注册动态创建的客户端脚本
     protected   override   void  Render(HtmlTextWriter writer)
    {
        
//  在RowDataBound中创建的自定义事件必须要在页中注册
        
//  通过重写Render方法来调用ClientScriptManager.RegisterForEventValidation。
        
//  通过GridViewRow.UniqueID返回行的唯一ID,按纽的唯一ID通过在行的唯一ID后附加“$ct100”而生成。
         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);
    }
}

 

 

代码
<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeFile = " EditIndividualCell.aspx.cs "   Inherits = " Control_EditIndividualCell "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >

< html  xmlns ="http://www.w3.org/1999/xhtml"   >
< head  id ="Head1"  runat ="server" >
    
< title > 在GridView中针对鼠标单击的某一独立单元格进行编辑 </ title >
 
</ head >
< body >
    
< form  id ="form1"  runat ="server" >

    
< div >
    
< asp:GridView  ID ="GridView1"  runat ="server"  AllowPaging ="True"  AutoGenerateColumns ="False"
        DataKeyNames
="EmployeeID"  DataSourceID ="SqlDataSource1"  AllowSorting ="True"  OnRowCommand ="GridView1_RowCommand"
        OnRowDataBound
="GridView1_RowDataBound"  OnRowUpdating ="GridView1_RowUpdating" >
        
< Columns >
            
< asp:ButtonField  Text ="SingleClick"  CommandName ="SingleClick"  Visible ="False"   />
            
< asp:BoundField  DataField ="EmployeeID"  HeaderText ="EmployeeID"  InsertVisible ="False"
                ReadOnly
="True"  SortExpression ="EmployeeID"   />
            
< asp:TemplateField  HeaderText ="LastName"  SortExpression ="LastName" >
                
< ItemTemplate >
                    
< asp:Label  ID ="lblLastName"  runat ="server"  Text ='<%#  Eval("LastName") % > '> </ asp:Label >
                    
< asp:TextBox  ID ="txtLastName"  runat ="server"  Text ='<%#  Eval("LastName") % > ' Visible="false"> </ asp:TextBox >
                
</ ItemTemplate >
            
</ asp:TemplateField >
            
< asp:TemplateField  HeaderText ="FirstName"  SortExpression ="FirstName" >
                
< ItemTemplate >
                    
< asp:Label  ID ="lblFirstName"  runat ="server"  Text ='<%#  Eval("FirstName") % > '> </ asp:Label >
                    
< asp:TextBox  ID ="txtFirstName"  runat ="server"  Text ='<%#  Eval("FirstName") % > ' Visible="false"> </ asp:TextBox >
                
</ ItemTemplate >
            
</ asp:TemplateField >
            
< asp:TemplateField  HeaderText ="Country"  SortExpression ="Country" >
                
< ItemTemplate >
                    
< asp:Label  ID ="lblCountry"  runat ="server"  Text ='<%#  Eval("Country") % > '> </ asp:Label >
                    
< asp:DropDownList  ID ="ddlCountry"  runat ="server"  Visible ="False"  AutoPostBack ="True"
                        DataSourceID
="SqlDataSource1"  DataTextField ="Country"  DataValueField ="Country" >
                    
</ asp:DropDownList >< asp:SqlDataSource  ID ="SqlDataSource1"  runat ="server"  ConnectionString ="<%$ ConnectionStrings:NorthwindConnectionString %>"
                        SelectCommand
="SELECT DISTINCT [Country] FROM [Employees]" ></ asp:SqlDataSource >
                
</ ItemTemplate >
            
</ asp:TemplateField >
        
</ Columns >
    
</ asp:GridView >
    
< asp:SqlDataSource  ID ="SqlDataSource1"  runat ="server"  ConnectionString ="<%$ ConnectionStrings:NorthwindConnectionString %>"
        DeleteCommand
="DELETE FROM [Employees] WHERE [EmployeeID] = @EmployeeID"  InsertCommand ="INSERT INTO [Employees] ([LastName], [FirstName], [Country]) VALUES (@LastName, @FirstName, @Country)"
        SelectCommand
="SELECT [LastName], [FirstName], [Country], [EmployeeID] FROM [Employees]"
        UpdateCommand
="UPDATE [Employees] SET [LastName] = @LastName, [FirstName] = @FirstName, [Country] = @Country WHERE [EmployeeID] = @EmployeeID" >
        
< DeleteParameters >
            
< asp:Parameter  Name ="EmployeeID"  Type ="Int32"   />
        
</ DeleteParameters >
        
< UpdateParameters >
            
< asp:Parameter  Name ="LastName"  Type ="String"   />
            
< asp:Parameter  Name ="FirstName"  Type ="String"   />
            
< asp:Parameter  Name ="Country"  Type ="String"   />
            
< asp:Parameter  Name ="EmployeeID"  Type ="Int32"   />
        
</ UpdateParameters >
        
< InsertParameters >
            
< asp:Parameter  Name ="LastName"  Type ="String"   />
            
< asp:Parameter  Name ="FirstName"  Type ="String"   />
            
< asp:Parameter  Name ="Country"  Type ="String"   />
        
</ InsertParameters >
    
</ asp:SqlDataSource >
    
< br  />
    
< br  />
    
< asp:Label  ID ="Message"  runat ="server"  ForeColor ="Red"  Font-Bold ="true" ></ asp:Label >

    
</ div >
    
</ form >
</ body >
</ html >

 

你可能感兴趣的:(GridView)