GridView 里的删除不起作用
里面的Delete不起作用,下面想用源码来解释这一现象,理解为什么删除不起作用:
当我点击次Delete时,在服务器端经历了以下步骤来处理:
this.RaisePostBackEvent(this._requestValueCollection);(Page 类里的ProcessRequest的一行)_requestValueCollection 为NameValueCollection 类
------
private void RaisePostBackEvent(NameValueCollection postData)
{
if (this._registeredControlThatRequireRaiseEvent != null)
{
this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
}
else
{
string str = postData["__EVENTTARGET"];
bool flag = !string.IsNullOrEmpty(str);
if (flag || (this.AutoPostBackControl != null))//此时AutoPostBack不为空
{
Control control = null;
if (flag)
{
control = this.FindControl(str);//最后找到GridView控件
}
if ((control != null) && (control.PostBackEventHandler != null))
{
string eventArgument = postData["__EVENTARGUMENT"];
this.RaisePostBackEvent(control.PostBackEventHandler, eventArgument);//单步进入此行,由于GridView实现了IPostBackEventHandler接口,所以可以在此处被传入,此时eventArguent 为:"Delete$0"
}
}
else
{
this.Validate();
}
}
}
------------------------------
以下调用:
protected virtual void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
sourceControl.RaisePostBackEvent(eventArgument);
}
----------------------------------
进入GridView的RaisePostBackEvent 方法 :
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
this.RaisePostBackEvent(eventArgument);
}
protected virtual void RaisePostBackEvent(string eventArgument) {
base.ValidateEvent(this.UniqueID, eventArgument);
int index = eventArgument.IndexOf('$');
if (index >= 0)
{
CommandEventArgs originalArgs = new CommandEventArgs(eventArgument.Substring(0, index), eventArgument.Substring(index + 1));
GridViewCommandEventArgs e = new GridViewCommandEventArgs(null, this, originalArgs);
this.HandleEvent(e, false, string.Empty);//根据e的值来做不同的处理,此时的e为:
}
}
下面会进入核心的 处理方法 :
private bool HandleEvent(EventArgs e, bool causesValidation, string validationGroup)
{
bool flag = false;
this.ResetModelValidationGroup(causesValidation, validationGroup);
GridViewCommandEventArgs args = e as GridViewCommandEventArgs;
if (args == null)
{
return flag;
}
this.OnRowCommand(args);
flag = true;
string commandName = args.CommandName;
if (StringUtil.EqualsIgnoreCase(commandName, "Select"))
{
this.HandleSelect(this.GetRowIndex(args.Row, (string) args.CommandArgument));
return flag;
}
if (StringUtil.EqualsIgnoreCase(commandName, "Page"))
{
string commandArgument = (string) args.CommandArgument;
int pageIndex = this.PageIndex;
if (StringUtil.EqualsIgnoreCase(commandArgument, "Next"))
{
pageIndex++;
}
else if (StringUtil.EqualsIgnoreCase(commandArgument, "Prev"))
{
pageIndex--;
}
else if (StringUtil.EqualsIgnoreCase(commandArgument, "First"))
{
pageIndex = 0;
}
else if (StringUtil.EqualsIgnoreCase(commandArgument, "Last"))
{
pageIndex = this.PageCount - 1;
}
else
{
pageIndex = Convert.ToInt32(commandArgument, CultureInfo.InvariantCulture) - 1;
}
this.HandlePage(pageIndex);
return flag;
}
if (StringUtil.EqualsIgnoreCase(commandName, "Sort"))
{
this.HandleSort((string) args.CommandArgument);
return flag;
}
if (StringUtil.EqualsIgnoreCase(commandName, "Edit"))
{
this.HandleEdit(this.GetRowIndex(args.Row, (string) args.CommandArgument));
return flag;
}
if (StringUtil.EqualsIgnoreCase(commandName, "Update"))
{
this.HandleUpdate(args.Row, this.GetRowIndex(args.Row, (string) args.CommandArgument), causesValidation);
return flag;
}
if (StringUtil.EqualsIgnoreCase(commandName, "Cancel"))
{
this.HandleCancel(this.GetRowIndex(args.Row, (string) args.CommandArgument));
return flag;
}
if (StringUtil.EqualsIgnoreCase(commandName, "Delete"))
{
this.HandleDelete(args.Row, this.GetRowIndex(args.Row, (string) args.CommandArgument));//由于 传入丢的参数为Delete所以会在此出进入.
return flag;
}
return this.HandleCommand(args.Row, this.GetRowIndex(args.Row, (string) args.CommandArgument), commandName);
}
---------------------------------
根据传递的参数来进入 以下HandleDelete方法来处理:
private void HandleDelete(GridViewRow row, int rowIndex)
{
DataSourceView data = null;
bool isBoundUsingDataSourceID = base.IsBoundUsingDataSourceID;
//此处就是ObjectDataSource被绑定后,GridView的方法就可以调用ObjectDataSource提供的方法
if (isBoundUsingDataSourceID)
{
data = this.GetData();此时的this就是:GridView,其基类:
//从ObjectDataSource获得绑定的方法得到数据,由于是使用的Delete所以不明白为何得到数据,所以以下会再做分析,是如何Delete更新会数据库的,并分析他的存在意义.
if (data == null)//显然得到了数据,类型为:System.Web.UI.WebControls.ObjectDataSourceView
{
throw new HttpException(System.Web.SR.GetString("GridView_DataSourceReturnedNullView", new object[] { this.ID }));
}
}
if ((row == null) && (rowIndex < this.Rows.Count))
{
row = this.Rows[rowIndex];
}
GridViewDeleteEventArgs e = new GridViewDeleteEventArgs(rowIndex);
if (row != null)
{
this.ExtractRowValues(e.Values, row, true, false);
}
if (this.DataKeys.Count > rowIndex)
{
foreach (DictionaryEntry entry in this.DataKeys[rowIndex].Values)
{
e.Keys.Add(entry.Key, entry.Value);
if (e.Values.Contains(entry.Key))
{
e.Values.Remove(entry.Key);
}
}
}
this.OnRowDeleting(e);//此行应该是把删除的操作发送给客户端
if (!e.Cancel)
{
this._deletedRowIndex = rowIndex;
if (isBoundUsingDataSourceID)
{
this._deleteKeys = e.Keys;
this._deleteValues = e.Values;
data.Delete(e.Keys, e.Values, new DataSourceViewOperationCallback(this.HandleDeleteCallback));//此行的功能应该是把删除的数据更新回数据库的过程. }
}
}
--------____________________
先分析:Data.Delete 方法:原型如下:
public virtual void Delete(IDictionary keys, IDictionary oldValues, DataSourceViewOperationCallback callback)
{
if (callback == null)
{
throw new ArgumentNullException("callback");
}
int affectedRecords = 0;
bool flag = false;
try
{
affectedRecords = this.ExecuteDelete(keys, oldValues);//后面调试发现,ObjectDataSource通过反射调用的
}
catch (Exception ex)
{
flag = true;
if (!callback(affectedRecords, ex))
{
throw;
}
}
finally
{
if (!flag)
{
callback(affectedRecords, null);
}
}
}
在 affectedRecords = this.ExecuteDelete(keys, oldValues);此处单步进入后:
通过反射调用方法,如何传递参数呢?
下面暂停一下,研究一小会儿反射,十分钟后.....
反射 的参数是在method的变量Parameter中 传入的,以键值对的形式传入,由于没有设置DataKeyNames属性,传入的值始终为空,(有一个有趣的现象 是,当传入的值为空时,执行反射的方法会发现整型的参数的变量为零?
)
其实在GridView1的DataKeyNames 中添加属性:UserId,即可.具体为什么要这么用,它和上面分析的Parameters有什么关系?下面分析源代码来理解:
DataKeyNames的定义如下:
public virtual string[] DataKeyNames
{
get
{
object obj2 = this._dataKeyNames;
if (obj2 != null)
{
return (string[]) ((string[]) obj2).Clone();
}
return new string[0];
}
set
{
if (!DataBoundControlHelper.CompareStringArrays(value, this.DataKeyNamesInternal))
{
if (value != null)
{
this._dataKeyNames = (string[]) value.Clone();
}
else
{
this._dataKeyNames = null;
}
this.ClearDataKeys();
if (base.Initialized)
{
base.RequiresDataBinding = true;
}
}
}
}
其实就是简单封装一下,没有啥关键性的东西.在这里 暂停一下,
看一下以上method的参数其实是由一个字典来赋值 的,其关键的 代码如下:
MergeDictionaries(this.DeleteParameters, this.DeleteParameters.GetValues(this._context, this._owner), dictionary2);
总结如下,this.DeleteParameters 此参数被赋值是由于在开始设置了DataKeyNames属性.但是DataKeyNames是在什么时候被赋值的?,先暂时研究到这里.
转载于:https://www.cnblogs.com/symphony2010/archive/2011/12/14/2287352.html
GridView 里的删除不起作用相关推荐
- 在GridView里做单选按钮,总结了三种方法
在GridView里做单选按钮,总结了三种方法 第一种方法:在GridView的模版列里加服务器端控件RadioButton,使用js控制单选 <p>使用模版列里加RadioButton& ...
- 利用yii2 gridview实现批量删除案例
作者:白狼 出处:http://www.manks.top/article/yii2_gridview_deleteall本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
- GridView里的一点小功能:截取多余字符、改变鼠标经过行的样式
将GRIDVIEW里多余的字符截取 只需要将选定的列改变为模板列,再编辑模板后,在DataBindings里,将比如Bind("concent")这样的改为 (Eval(" ...
- 在GridView里使用CheckBox
在GridView的第一列使用CheckBox控制每一行数据,是经常使用的,这里面我要记录的是全选.全消.选中行的底色更改,还有就是在提交数据的时候,取选中的行的编号等功能 aspx页面定义: < ...
- 【回眸】关于网线水晶头里八根线的作用
文章目录 网线水晶头里八根线的作用 网线的标准 在制作网线时,根据实际的需要,包括以下两种制作标准: EIA/TIA 568A标准 EIA/TIA 568B标准 网线八根线的作用 网线中第1根线芯-- ...
- Mozilla里永久删除的邮件如何恢复
Mozilla的受众人群非常多,大批用户喜欢在个人的计算机内安装Mozilla客户端用户收发邮件,有的时候邮件过多,尤其是一些垃圾邮件的出现,让我们养成了定期删除邮件的习惯,但是在删除邮件的过程中,一 ...
- C语言里的和*的简单作用理解
##C语言里的&和*的简单作用理解 自己在C里,关于&与*的作用老是迷糊了好久,学了也是忘记,所以在此再做笔记,以便给有同样困扰的小白一起学习. 首先我们要知道,一个变量存在计算机 ...
- ASP.NET 中关GridView里加入CheckBox 在后台获取不到选中状态的问题
<!-- 在GridView里添加CheckBox选择控件 !--> <ItemTemplate><asp:CheckBox ID="CheckBox" ...
- 计算机上显示F怎么取消,去掉任务栏安全删除硬件里出现删除硬盘驱动器C,D,E,F和光驱的方法...
去掉任务栏安全删除硬件里出现删除硬盘驱动器C,D,E,F和光驱的方法 发布时间:2012-09-03 15:10:59 作者:佚名 我要评论 任务栏"安全删除硬件"里出现删 ...
最新文章
- Python 调用matplotlib模块绘制柱状图
- 【C 语言】文件操作 ( C 语言中的文件操作函数 | 磁盘与内存缓冲区 | 缓冲区工作机制 )
- 小红伞和NOD32基于源码的免杀经验总结
- python time模块
- Mysql权限控制 - 允许用户远程连接
- [ios]ios读写文件本地数据
- Spring boot mongoDB的总结
- 室内定位之蓝牙定位精度(蓝牙AOA定位)
- mysql每组排序后取前2条,并修改数据
- 【机器学习】【决策树】C4.5算法,详解+python代码实现
- 如何防止你的爬虫被网管一巴掌拍死
- SCI从入门到精通(第一版)
- 5G时代IDC数据中心经历变革,分布式云存储服务器将独占鳌头
- 【AIGC】大模型协作系统 HuggingGPT 深度解析
- 动态规划-(基本知识总结)
- 教师回应幼儿求助行为的问题及对策研究
- java学习日记-接口
- 阿里测试开发面经一面
- 肉眼看不见的信息传递圈层
- ArcGIS打开ArcToolbox闪退解决方法