里面的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 里的删除不起作用相关推荐

  1. 在GridView里做单选按钮,总结了三种方法

    在GridView里做单选按钮,总结了三种方法 第一种方法:在GridView的模版列里加服务器端控件RadioButton,使用js控制单选 <p>使用模版列里加RadioButton& ...

  2. 利用yii2 gridview实现批量删除案例

    作者:白狼 出处:http://www.manks.top/article/yii2_gridview_deleteall本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  3. GridView里的一点小功能:截取多余字符、改变鼠标经过行的样式

    将GRIDVIEW里多余的字符截取 只需要将选定的列改变为模板列,再编辑模板后,在DataBindings里,将比如Bind("concent")这样的改为 (Eval(" ...

  4. 在GridView里使用CheckBox

    在GridView的第一列使用CheckBox控制每一行数据,是经常使用的,这里面我要记录的是全选.全消.选中行的底色更改,还有就是在提交数据的时候,取选中的行的编号等功能 aspx页面定义: < ...

  5. 【回眸】关于网线水晶头里八根线的作用

    文章目录 网线水晶头里八根线的作用 网线的标准 在制作网线时,根据实际的需要,包括以下两种制作标准: EIA/TIA 568A标准 EIA/TIA 568B标准 网线八根线的作用 网线中第1根线芯-- ...

  6. Mozilla里永久删除的邮件如何恢复

    Mozilla的受众人群非常多,大批用户喜欢在个人的计算机内安装Mozilla客户端用户收发邮件,有的时候邮件过多,尤其是一些垃圾邮件的出现,让我们养成了定期删除邮件的习惯,但是在删除邮件的过程中,一 ...

  7. C语言里的和*的简单作用理解

    ##C语言里的&和*的简单作用理解   自己在C里,关于&与*的作用老是迷糊了好久,学了也是忘记,所以在此再做笔记,以便给有同样困扰的小白一起学习. 首先我们要知道,一个变量存在计算机 ...

  8. ASP.NET 中关GridView里加入CheckBox 在后台获取不到选中状态的问题

    <!-- 在GridView里添加CheckBox选择控件 !--> <ItemTemplate><asp:CheckBox ID="CheckBox" ...

  9. 计算机上显示F怎么取消,去掉任务栏安全删除硬件里出现删除硬盘驱动器C,D,E,F和光驱的方法...

    去掉任务栏安全删除硬件里出现删除硬盘驱动器C,D,E,F和光驱的方法 发布时间:2012-09-03 15:10:59   作者:佚名   我要评论 任务栏"安全删除硬件"里出现删 ...

最新文章

  1. Python 调用matplotlib模块绘制柱状图
  2. 【C 语言】文件操作 ( C 语言中的文件操作函数 | 磁盘与内存缓冲区 | 缓冲区工作机制 )
  3. 小红伞和NOD32基于源码的免杀经验总结
  4. python time模块
  5. Mysql权限控制 - 允许用户远程连接
  6. [ios]ios读写文件本地数据
  7. Spring boot mongoDB的总结
  8. 室内定位之蓝牙定位精度(蓝牙AOA定位)
  9. mysql每组排序后取前2条,并修改数据
  10. 【机器学习】【决策树】C4.5算法,详解+python代码实现
  11. 如何防止你的爬虫被网管一巴掌拍死
  12. SCI从入门到精通(第一版)
  13. 5G时代IDC数据中心经历变革,分布式云存储服务器将独占鳌头
  14. 【AIGC】大模型协作系统 HuggingGPT 深度解析
  15. 动态规划-(基本知识总结)
  16. 教师回应幼儿求助行为的问题及对策研究
  17. java学习日记-接口
  18. 阿里测试开发面经一面
  19. 肉眼看不见的信息传递圈层
  20. ArcGIS打开ArcToolbox闪退解决方法

热门文章

  1. 怀念 儿时课本贴图,你还记得课文名吗
  2. PPP协议详细图解实验
  3. NA,NP,IE学习之路
  4. 卧加加工斜孔怎么计算机械坐标,卧加B轴旋转后坐标怎么计算
  5. C语言中结构体的位域(bit-fields)
  6. 双向口和准双向口操作的不同!
  7. ES6-let const
  8. 常见拒绝服务攻击行为特征与防御方法
  9. android源码分析-深入MessageQueue
  10. FFmpeg-20160422-snapshot-bin