GridView 里的删除不起作用

 

image

里面的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);此处单步进入后:

image

image

通过反射调用方法,如何传递参数呢?

下面暂停一下,研究一小会儿反射,十分钟后.....

反射 的参数是在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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值