Gridview中RowUpdating事件e.NewValues.Add(key,value)与e.NewValues[_columnKeys[i2]] = 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>
原文地址:https://www.cnblogs.com/quanhai/p/1685807.html