先从OnItemUpdating和OnItemUpdated事件开始:
protected virtual void OnItemUpdating(DetailsViewUpdateEventArgs e)
{
bool flag1 = base.IsBoundUsingDataSourceID;
DetailsViewUpdateEventHandler handler1 = (DetailsViewUpdateEventHandler) base.Events[DetailsView.EventItemUpdating];
if (handler1 != null)
{
handler1(this, e);
}
else if (!flag1 && !e.Cancel)
{
throw new HttpException(System.Web.SR.GetString("DetailsView_UnhandledEvent", new object[] { this.ID, "ItemUpdating" }));
}
}
{
bool flag1 = base.IsBoundUsingDataSourceID;
DetailsViewUpdateEventHandler handler1 = (DetailsViewUpdateEventHandler) base.Events[DetailsView.EventItemUpdating];
if (handler1 != null)
{
handler1(this, e);
}
else if (!flag1 && !e.Cancel)
{
throw new HttpException(System.Web.SR.GetString("DetailsView_UnhandledEvent", new object[] { this.ID, "ItemUpdating" }));
}
}
protected virtual void OnItemUpdated(DetailsViewUpdatedEventArgs e)
{
DetailsViewUpdatedEventHandler handler1 = (DetailsViewUpdatedEventHandler) base.Events[DetailsView.EventItemUpdated];
if (handler1 != null)
{
handler1(this, e);
}
}
{
DetailsViewUpdatedEventHandler handler1 = (DetailsViewUpdatedEventHandler) base.Events[DetailsView.EventItemUpdated];
if (handler1 != null)
{
handler1(this, e);
}
}
从这两个方法中看不出什么,只是一个简单的事件触发函数。下面看看它们被调用的地方:
1. OnItemUpdating方法被HandleUpdate方法调用:
private void HandleUpdate(string commandArg, bool causesValidation)
{
if ((!causesValidation || (this.Page == null)) || this.Page.IsValid)
{
if (this.Mode != DetailsViewMode.Edit)
{
throw new HttpException(System.Web.SR.GetString("DetailsViewFormView_ControlMustBeInEditMode", new object[] { "DetailsView", this.ID }));
}
if (this.PageIndex >= 0)
{
DataSourceView view1 = null;
bool flag1 = base.IsBoundUsingDataSourceID;
if (flag1)
{
view1 = this.GetData();
if (view1 == null)
{
throw new HttpException(System.Web.SR.GetString("View_DataSourceReturnedNullView", new object[] { this.ID }));
}
}
DetailsViewUpdateEventArgs args1 = new DetailsViewUpdateEventArgs(commandArg);
if (flag1)
{
foreach (DictionaryEntry entry1 in this.BoundFieldValues)
{
args1.OldValues.Add(entry1.Key, entry1.Value);
}
this.ExtractRowValues(args1.NewValues, false, true);
foreach (DictionaryEntry entry2 in this.DataKey.Values)
{
args1.Keys.Add(entry2.Key, entry2.Value);
}
}
this.OnItemUpdating(args1);
if (!args1.Cancel && flag1)
{
this._updateKeys = args1.Keys;
this._updateNewValues = args1.NewValues;
this._updateOldValues = args1.OldValues;
view1.Update(args1.Keys, args1.NewValues, args1.OldValues, new DataSourceViewOperationCallback(this.HandleUpdateCallback));
}
}
}
}
{
if ((!causesValidation || (this.Page == null)) || this.Page.IsValid)
{
if (this.Mode != DetailsViewMode.Edit)
{
throw new HttpException(System.Web.SR.GetString("DetailsViewFormView_ControlMustBeInEditMode", new object[] { "DetailsView", this.ID }));
}
if (this.PageIndex >= 0)
{
DataSourceView view1 = null;
bool flag1 = base.IsBoundUsingDataSourceID;
if (flag1)
{
view1 = this.GetData();
if (view1 == null)
{
throw new HttpException(System.Web.SR.GetString("View_DataSourceReturnedNullView", new object[] { this.ID }));
}
}
DetailsViewUpdateEventArgs args1 = new DetailsViewUpdateEventArgs(commandArg);
if (flag1)
{
foreach (DictionaryEntry entry1 in this.BoundFieldValues)
{
args1.OldValues.Add(entry1.Key, entry1.Value);
}
this.ExtractRowValues(args1.NewValues, false, true);
foreach (DictionaryEntry entry2 in this.DataKey.Values)
{
args1.Keys.Add(entry2.Key, entry2.Value);
}
}
this.OnItemUpdating(args1);
if (!args1.Cancel && flag1)
{
this._updateKeys = args1.Keys;
this._updateNewValues = args1.NewValues;
this._updateOldValues = args1.OldValues;
view1.Update(args1.Keys, args1.NewValues, args1.OldValues, new DataSourceViewOperationCallback(this.HandleUpdateCallback));
}
}
}
}
2. OnItemUpdated方法被HandleUpdateCallback调用
private bool HandleUpdateCallback(int affectedRows, Exception ex)
{
DetailsViewUpdatedEventArgs args1 = new DetailsViewUpdatedEventArgs(affectedRows, ex);
args1.SetOldValues(this._updateOldValues);
args1.SetNewValues(this._updateNewValues);
args1.SetKeys(this._updateKeys);
this.OnItemUpdated(args1);
this._updateKeys = null;
this._updateOldValues = null;
this._updateNewValues = null;
if ((ex != null) && !args1.ExceptionHandled)
{
return false;
}
if (!args1.KeepInEditMode)
{
DetailsViewModeEventArgs args2 = new DetailsViewModeEventArgs(this.DefaultMode, false);
this.OnModeChanging(args2);
if (!args2.Cancel)
{
this.Mode = args2.NewMode;
this.OnModeChanged(EventArgs.Empty);
base.RequiresDataBinding = true;
}
}
return true;
}
{
DetailsViewUpdatedEventArgs args1 = new DetailsViewUpdatedEventArgs(affectedRows, ex);
args1.SetOldValues(this._updateOldValues);
args1.SetNewValues(this._updateNewValues);
args1.SetKeys(this._updateKeys);
this.OnItemUpdated(args1);
this._updateKeys = null;
this._updateOldValues = null;
this._updateNewValues = null;
if ((ex != null) && !args1.ExceptionHandled)
{
return false;
}
if (!args1.KeepInEditMode)
{
DetailsViewModeEventArgs args2 = new DetailsViewModeEventArgs(this.DefaultMode, false);
this.OnModeChanging(args2);
if (!args2.Cancel)
{
this.Mode = args2.NewMode;
this.OnModeChanged(EventArgs.Empty);
base.RequiresDataBinding = true;
}
}
return true;
}
下面看看HandleUpdate,HandleUpdateCallback这两个方法被调用的地方:
1. HandleUpdate方法被调用的地方
private bool HandleEvent(EventArgs e, bool causesValidation, string validationGroup)
{
bool flag1 = false;
if (causesValidation && (this.Page != null))
{
this.Page.Validate(validationGroup);
}
DetailsViewCommandEventArgs args1 = e as DetailsViewCommandEventArgs;
if (args1 != null)
{
this.OnItemCommand(args1);
flag1 = true;
string text1 = args1.CommandName;
int num1 = this.PageIndex;
if (StringUtil.EqualsIgnoreCase(text1, "Page"))
{
string text2 = (string) args1.CommandArgument;
if (StringUtil.EqualsIgnoreCase(text2, "Next"))
{
num1++;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Prev"))
{
num1--;
}
else if (StringUtil.EqualsIgnoreCase(text2, "First"))
{
num1 = 0;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Last"))
{
if (base.IsViewStateEnabled)
{
num1 = this.PageCount - 1;
}
else
{
num1 = 0x7fffffff;
}
}
else
{
num1 = Convert.ToInt32(text2, CultureInfo.InvariantCulture) - 1;
}
this.HandlePage(num1);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Edit"))
{
this.HandleEdit();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Update"))
{
this.HandleUpdate((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Cancel"))
{
this.HandleCancel();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Delete"))
{
this.HandleDelete((string) args1.CommandArgument);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Insert"))
{
this.HandleInsert((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "New"))
{
this.HandleNew();
}
}
return flag1;
}
{
bool flag1 = false;
if (causesValidation && (this.Page != null))
{
this.Page.Validate(validationGroup);
}
DetailsViewCommandEventArgs args1 = e as DetailsViewCommandEventArgs;
if (args1 != null)
{
this.OnItemCommand(args1);
flag1 = true;
string text1 = args1.CommandName;
int num1 = this.PageIndex;
if (StringUtil.EqualsIgnoreCase(text1, "Page"))
{
string text2 = (string) args1.CommandArgument;
if (StringUtil.EqualsIgnoreCase(text2, "Next"))
{
num1++;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Prev"))
{
num1--;
}
else if (StringUtil.EqualsIgnoreCase(text2, "First"))
{
num1 = 0;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Last"))
{
if (base.IsViewStateEnabled)
{
num1 = this.PageCount - 1;
}
else
{
num1 = 0x7fffffff;
}
}
else
{
num1 = Convert.ToInt32(text2, CultureInfo.InvariantCulture) - 1;
}
this.HandlePage(num1);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Edit"))
{
this.HandleEdit();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Update"))
{
this.HandleUpdate((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Cancel"))
{
this.HandleCancel();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Delete"))
{
this.HandleDelete((string) args1.CommandArgument);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Insert"))
{
this.HandleInsert((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "New"))
{
this.HandleNew();
}
}
return flag1;
}
public virtual void UpdateItem(bool causesValidation)
{
this.HandleUpdate(string.Empty, causesValidation);
}
{
this.HandleUpdate(string.Empty, causesValidation);
}
2. HandleUpdateCallback方法被调用的地方
private void HandleUpdate(string commandArg, bool causesValidation)
{
if ((!causesValidation || (this.Page == null)) || this.Page.IsValid)
{
if (this.Mode != DetailsViewMode.Edit)
{
throw new HttpException(System.Web.SR.GetString("DetailsViewFormView_ControlMustBeInEditMode", new object[] { "DetailsView", this.ID }));
}
if (this.PageIndex >= 0)
{
DataSourceView view1 = null;
bool flag1 = base.IsBoundUsingDataSourceID;
if (flag1)
{
view1 = this.GetData();
if (view1 == null)
{
throw new HttpException(System.Web.SR.GetString("View_DataSourceReturnedNullView", new object[] { this.ID }));
}
}
DetailsViewUpdateEventArgs args1 = new DetailsViewUpdateEventArgs(commandArg);
if (flag1)
{
foreach (DictionaryEntry entry1 in this.BoundFieldValues)
{
args1.OldValues.Add(entry1.Key, entry1.Value);
}
this.ExtractRowValues(args1.NewValues, false, true);
foreach (DictionaryEntry entry2 in this.DataKey.Values)
{
args1.Keys.Add(entry2.Key, entry2.Value);
}
}
this.OnItemUpdating(args1);
if (!args1.Cancel && flag1)
{
this._updateKeys = args1.Keys;
this._updateNewValues = args1.NewValues;
this._updateOldValues = args1.OldValues;
view1.Update(args1.Keys, args1.NewValues, args1.OldValues, new DataSourceViewOperationCallback(this.HandleUpdateCallback));
}
}
}
}
{
if ((!causesValidation || (this.Page == null)) || this.Page.IsValid)
{
if (this.Mode != DetailsViewMode.Edit)
{
throw new HttpException(System.Web.SR.GetString("DetailsViewFormView_ControlMustBeInEditMode", new object[] { "DetailsView", this.ID }));
}
if (this.PageIndex >= 0)
{
DataSourceView view1 = null;
bool flag1 = base.IsBoundUsingDataSourceID;
if (flag1)
{
view1 = this.GetData();
if (view1 == null)
{
throw new HttpException(System.Web.SR.GetString("View_DataSourceReturnedNullView", new object[] { this.ID }));
}
}
DetailsViewUpdateEventArgs args1 = new DetailsViewUpdateEventArgs(commandArg);
if (flag1)
{
foreach (DictionaryEntry entry1 in this.BoundFieldValues)
{
args1.OldValues.Add(entry1.Key, entry1.Value);
}
this.ExtractRowValues(args1.NewValues, false, true);
foreach (DictionaryEntry entry2 in this.DataKey.Values)
{
args1.Keys.Add(entry2.Key, entry2.Value);
}
}
this.OnItemUpdating(args1);
if (!args1.Cancel && flag1)
{
this._updateKeys = args1.Keys;
this._updateNewValues = args1.NewValues;
this._updateOldValues = args1.OldValues;
view1.Update(args1.Keys, args1.NewValues, args1.OldValues, new DataSourceViewOperationCallback(this.HandleUpdateCallback));
}
}
}
}
从上面可以看到:
HandleUpdateCallback 被 HandleUpdate 方法调用。
HandleUpdate 被 HandleEvent 和 UpdateItem 方法调用。
现在看一下 HandleEvent 和 UpdateItem 方法调用:
1. HandleEvent方法被调用的地方:
protected override bool OnBubbleEvent(object source, EventArgs e)
{
bool flag1 = false;
string text1 = string.Empty;
DetailsViewCommandEventArgs args1 = e as DetailsViewCommandEventArgs;
if (args1 != null)
{
IButtonControl control1 = args1.CommandSource as IButtonControl;
if (control1 != null)
{
flag1 = control1.CausesValidation;
text1 = control1.ValidationGroup;
}
}
return this.HandleEvent(e, flag1, text1);
}
{
bool flag1 = false;
string text1 = string.Empty;
DetailsViewCommandEventArgs args1 = e as DetailsViewCommandEventArgs;
if (args1 != null)
{
IButtonControl control1 = args1.CommandSource as IButtonControl;
if (control1 != null)
{
flag1 = control1.CausesValidation;
text1 = control1.ValidationGroup;
}
}
return this.HandleEvent(e, flag1, text1);
}
protected virtual void RaisePostBackEvent(string eventArgument)
{
base.ValidateEvent(this.UniqueID, eventArgument);
int num1 = eventArgument.IndexOf('$');
if (num1 >= 0)
{
CommandEventArgs args1 = new CommandEventArgs(eventArgument.Substring(0, num1), eventArgument.Substring(num1 + 1));
DetailsViewCommandEventArgs args2 = new DetailsViewCommandEventArgs(this, args1);
this.HandleEvent(args2, false, string.Empty);
}
}
{
base.ValidateEvent(this.UniqueID, eventArgument);
int num1 = eventArgument.IndexOf('$');
if (num1 >= 0)
{
CommandEventArgs args1 = new CommandEventArgs(eventArgument.Substring(0, num1), eventArgument.Substring(num1 + 1));
DetailsViewCommandEventArgs args2 = new DetailsViewCommandEventArgs(this, args1);
this.HandleEvent(args2, false, string.Empty);
}
}
2. UpdateItem 方法是个虚方法,未找到被调用的地方,不过可以直接调用DetailsView.UpdateItem()方法。
下面研究RaisePostBackEvent被调用的地方:
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
this.RaisePostBackEvent(eventArgument);
}
{
this.RaisePostBackEvent(eventArgument);
}
这里的IPostBackEventHandler是DetailsView继承的接口之一。
最后集中研究OnBubbleEvent和IPostBackEventHandler.RaisePostBackEvent方法被调用的地方,这里要涉及到页面的生命周期:
DetailsView.OnBubbleEvent 方法:
确定 Web 服务器控件的事件是否沿页的用户界面 (UI) 服务器控件层次结构向上传递。
命名空间:System.Web.UI.WebControls
程序集:System.Web(在 system.web.dll 中)
语法
Visual Basic(声明)
Protected Overrides Function OnBubbleEvent ( _
source As Object, _
e As EventArgs _
) As Boolean
Visual Basic(用法)
Dim source As Object
Dim e As EventArgs
Dim returnValue As Boolean
returnValue = Me.OnBubbleEvent(source, e)
C#
protected override bool OnBubbleEvent (
Object source,
EventArgs e
)
C++
protected:
virtual bool OnBubbleEvent (
Object^ source,
EventArgs^ e
) override
J#
protected boolean OnBubbleEvent (
Object source,
EventArgs e
)
JScript
protected override function OnBubbleEvent (
source : Object,
e : EventArgs
) : boolean
参数
source
事件源。
e
包含事件数据的 EventArgs。
返回值
如果事件已被取消,则为 true;否则为 false。
备注
OnBubbleEvent 方法实现了 Control.OnBubbleEvent 方法以将事件从子控件传递到页层次结构。
给继承者的说明 在派生类中重写 OnBubbleEvent 时,一定要调用基类的 OnBubbleEvent 方法,以便已注册的委托对事件进行接收
命名空间:System.Web.UI.WebControls
程序集:System.Web(在 system.web.dll 中)
语法
Visual Basic(声明)
Protected Overrides Function OnBubbleEvent ( _
source As Object, _
e As EventArgs _
) As Boolean
Visual Basic(用法)
Dim source As Object
Dim e As EventArgs
Dim returnValue As Boolean
returnValue = Me.OnBubbleEvent(source, e)
C#
protected override bool OnBubbleEvent (
Object source,
EventArgs e
)
C++
protected:
virtual bool OnBubbleEvent (
Object^ source,
EventArgs^ e
) override
J#
protected boolean OnBubbleEvent (
Object source,
EventArgs e
)
JScript
protected override function OnBubbleEvent (
source : Object,
e : EventArgs
) : boolean
参数
source
事件源。
e
包含事件数据的 EventArgs。
返回值
如果事件已被取消,则为 true;否则为 false。
备注
OnBubbleEvent 方法实现了 Control.OnBubbleEvent 方法以将事件从子控件传递到页层次结构。
给继承者的说明 在派生类中重写 OnBubbleEvent 时,一定要调用基类的 OnBubbleEvent 方法,以便已注册的委托对事件进行接收
Control.OnBubbleEvent 方法:
确定服务器控件的事件是否沿页的 UI 服务器控件层次结构向上传递。
命名空间:System.Web.UI
程序集:System.Web(在 system.web.dll 中)
语法
Visual Basic(声明)
Protected Overridable Function OnBubbleEvent ( _
source As Object, _
args As EventArgs _
) As Boolean
Visual Basic(用法)
Dim source As Object
Dim args As EventArgs
Dim returnValue As Boolean
returnValue = Me.OnBubbleEvent(source, args)
C#
protected virtual bool OnBubbleEvent (
Object source,
EventArgs args
)
C++
protected:
virtual bool OnBubbleEvent (
Object^ source,
EventArgs^ args
)
J#
protected boolean OnBubbleEvent (
Object source,
EventArgs args
)
JScript
protected function OnBubbleEvent (
source : Object,
args : EventArgs
) : boolean
参数
source
事件源。
args
包含事件数据的 EventArgs 对象。
返回值
如果事件已被取消,则为 true;否则为 false。默认为 false。
备注
ASP.NET 服务器控件(如 Repeater、DataList 和 DataGrid Web 控件)可以包含引发事件的子控件。例如,DataGrid 控件中的每一行都可以包含一个或多个由模板动态创建的按钮。不是由每个按钮分别引发事件,而是嵌套控件中的事件“冒泡”,即它们被发送到命名容器。命名容器然后引发带参数值的名为 ItemCommand 的一般事件。这些值使您可以确定引发原始事件的单个控件。通过响应这一事件,可以不必为子控件分别编写事件处理方法。
示例
下面的示例重写自定义 ASP.NET 服务器控件 ParentControl 中的 OnBubbleEvent 方法。在 ParentControl 的子控件调用 RaiseBubbleEvent 方法时会调用此方法。当这种情况发生时,ParentControl 类将两个字符串写入包含 ASP.NET 的页中,第一个字符串说明其 OnBubbleEvent 方法已被调用,第二个字符串标识 RaiseBubbleEvent 方法的源控件。
Visual Basic 复制代码
Public Class ParentControl
Inherits Control
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Protected Overrides Function OnBubbleEvent(sender As Object, e As EventArgs) As Boolean
Context.Response.Write("<br><br>ParentControl's OnBubbleEvent called.")
Context.Response.Write(("<br>Source of event is: " + sender.ToString()))
Return True
End Function 'OnBubbleEvent
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Protected Overrides Sub Render(myWriter As HtmlTextWriter)
myWriter.Write("ParentControl")
RenderChildren(myWriter)
End Sub 'Render
End Class 'ParentControl
_
C# 复制代码
public class ParentControl : Control
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
protected override bool OnBubbleEvent(object sender, EventArgs e)
{
Context.Response.Write("<br><br>ParentControl's OnBubbleEvent called.");
Context.Response.Write("<br>Source of event is: " + sender.ToString());
return true;
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
protected override void Render( HtmlTextWriter myWriter)
{
myWriter.Write("ParentControl");
RenderChildren(myWriter);
}
}
命名空间:System.Web.UI
程序集:System.Web(在 system.web.dll 中)
语法
Visual Basic(声明)
Protected Overridable Function OnBubbleEvent ( _
source As Object, _
args As EventArgs _
) As Boolean
Visual Basic(用法)
Dim source As Object
Dim args As EventArgs
Dim returnValue As Boolean
returnValue = Me.OnBubbleEvent(source, args)
C#
protected virtual bool OnBubbleEvent (
Object source,
EventArgs args
)
C++
protected:
virtual bool OnBubbleEvent (
Object^ source,
EventArgs^ args
)
J#
protected boolean OnBubbleEvent (
Object source,
EventArgs args
)
JScript
protected function OnBubbleEvent (
source : Object,
args : EventArgs
) : boolean
参数
source
事件源。
args
包含事件数据的 EventArgs 对象。
返回值
如果事件已被取消,则为 true;否则为 false。默认为 false。
备注
ASP.NET 服务器控件(如 Repeater、DataList 和 DataGrid Web 控件)可以包含引发事件的子控件。例如,DataGrid 控件中的每一行都可以包含一个或多个由模板动态创建的按钮。不是由每个按钮分别引发事件,而是嵌套控件中的事件“冒泡”,即它们被发送到命名容器。命名容器然后引发带参数值的名为 ItemCommand 的一般事件。这些值使您可以确定引发原始事件的单个控件。通过响应这一事件,可以不必为子控件分别编写事件处理方法。
示例
下面的示例重写自定义 ASP.NET 服务器控件 ParentControl 中的 OnBubbleEvent 方法。在 ParentControl 的子控件调用 RaiseBubbleEvent 方法时会调用此方法。当这种情况发生时,ParentControl 类将两个字符串写入包含 ASP.NET 的页中,第一个字符串说明其 OnBubbleEvent 方法已被调用,第二个字符串标识 RaiseBubbleEvent 方法的源控件。
Visual Basic 复制代码
Public Class ParentControl
Inherits Control
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Protected Overrides Function OnBubbleEvent(sender As Object, e As EventArgs) As Boolean
Context.Response.Write("<br><br>ParentControl's OnBubbleEvent called.")
Context.Response.Write(("<br>Source of event is: " + sender.ToString()))
Return True
End Function 'OnBubbleEvent
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Protected Overrides Sub Render(myWriter As HtmlTextWriter)
myWriter.Write("ParentControl")
RenderChildren(myWriter)
End Sub 'Render
End Class 'ParentControl
_
C# 复制代码
public class ParentControl : Control
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
protected override bool OnBubbleEvent(object sender, EventArgs e)
{
Context.Response.Write("<br><br>ParentControl's OnBubbleEvent called.");
Context.Response.Write("<br>Source of event is: " + sender.ToString());
return true;
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
protected override void Render( HtmlTextWriter myWriter)
{
myWriter.Write("ParentControl");
RenderChildren(myWriter);
}
}
至此上述方法和事件之间的关系总结如下图:
下面来研究OnItemCommand方法:
protected virtual void OnItemCommand(DetailsViewCommandEventArgs e)
{
DetailsViewCommandEventHandler handler1 = (DetailsViewCommandEventHandler) base.Events[DetailsView.EventItemCommand];
if (handler1 != null)
{
handler1(this, e);
}
}
OnItemCommand方法被调用的地方:{
DetailsViewCommandEventHandler handler1 = (DetailsViewCommandEventHandler) base.Events[DetailsView.EventItemCommand];
if (handler1 != null)
{
handler1(this, e);
}
}
private bool HandleEvent(EventArgs e, bool causesValidation, string validationGroup)
{
bool flag1 = false;
if (causesValidation && (this.Page != null))
{
this.Page.Validate(validationGroup);
}
DetailsViewCommandEventArgs args1 = e as DetailsViewCommandEventArgs;
if (args1 != null)
{
this.OnItemCommand(args1);
flag1 = true;
string text1 = args1.CommandName;
int num1 = this.PageIndex;
if (StringUtil.EqualsIgnoreCase(text1, "Page"))
{
string text2 = (string) args1.CommandArgument;
if (StringUtil.EqualsIgnoreCase(text2, "Next"))
{
num1++;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Prev"))
{
num1--;
}
else if (StringUtil.EqualsIgnoreCase(text2, "First"))
{
num1 = 0;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Last"))
{
if (base.IsViewStateEnabled)
{
num1 = this.PageCount - 1;
}
else
{
num1 = 0x7fffffff;
}
}
else
{
num1 = Convert.ToInt32(text2, CultureInfo.InvariantCulture) - 1;
}
this.HandlePage(num1);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Edit"))
{
this.HandleEdit();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Update"))
{
this.HandleUpdate((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Cancel"))
{
this.HandleCancel();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Delete"))
{
this.HandleDelete((string) args1.CommandArgument);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Insert"))
{
this.HandleInsert((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "New"))
{
this.HandleNew();
}
}
return flag1;
}
也是在HandleEvent方法中被调用的。{
bool flag1 = false;
if (causesValidation && (this.Page != null))
{
this.Page.Validate(validationGroup);
}
DetailsViewCommandEventArgs args1 = e as DetailsViewCommandEventArgs;
if (args1 != null)
{
this.OnItemCommand(args1);
flag1 = true;
string text1 = args1.CommandName;
int num1 = this.PageIndex;
if (StringUtil.EqualsIgnoreCase(text1, "Page"))
{
string text2 = (string) args1.CommandArgument;
if (StringUtil.EqualsIgnoreCase(text2, "Next"))
{
num1++;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Prev"))
{
num1--;
}
else if (StringUtil.EqualsIgnoreCase(text2, "First"))
{
num1 = 0;
}
else if (StringUtil.EqualsIgnoreCase(text2, "Last"))
{
if (base.IsViewStateEnabled)
{
num1 = this.PageCount - 1;
}
else
{
num1 = 0x7fffffff;
}
}
else
{
num1 = Convert.ToInt32(text2, CultureInfo.InvariantCulture) - 1;
}
this.HandlePage(num1);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Edit"))
{
this.HandleEdit();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Update"))
{
this.HandleUpdate((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Cancel"))
{
this.HandleCancel();
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Delete"))
{
this.HandleDelete((string) args1.CommandArgument);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "Insert"))
{
this.HandleInsert((string) args1.CommandArgument, causesValidation);
return flag1;
}
if (StringUtil.EqualsIgnoreCase(text1, "New"))
{
this.HandleNew();
}
}
return flag1;
}
但是在HandleEvent方法中,OnItemCommand在HandleUpdate方法之前,这就是说,OnItemCommand中的Update方法,在OnItemUpdating和OnItemUpdated方法之前。
在这里将前面的图完善一下:
下面看一下DataSourceID中对应的UpdateMethod方法的运行原理:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架