1. 如何引发一个Postback. Asp.net 内置有2 种方法可以引起页面的postback。
1> HTML 元素 <input type="submit"> 和 <input type="image"> 在 客户端点击的时候将引发postback, asp.net 内置了对于这2 个标签的支持,
不需要我们做任何事情, 只需要将按钮的type 注册为Image 或者是 submit . 那么在点击按钮的时候, 按钮就自动引发一个postback.
2> 其他的html标签 比如说link, 或者一个 文本框默认是不会引发postback 的,那么怎么办呢?别着急, asp.net 为我们提供了另外一个机制来引发postback.
那就是__doPostBack 函数。
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, this.Page.ClientScript.GetPostBackEventReference(this, Argument, false));
它通过GetPostBackEventReference 方法将客户端的Onclick 事件引入到服务器控件的postback 机制中。
在测试页面中把 控件的Argument 属性值设为“arg”, 然后查看页面源代码, 看看 GetPostBackEventReference 具体做了些什么事情。
private
string
GetPostBackEventReference(Control control,
string
argument,
bool
forUrl,
bool
registerForEventValidation)
{
if
(control
==
null
)
{
throw
new
ArgumentNullException(
"
control
"
);
}
this
._owner.RegisterPostBackScript();
string
uniqueID
=
control.UniqueID;
if
(registerForEventValidation)
{
this
.RegisterForEventValidation(uniqueID, argument);
}
if
((control.EnableLegacyRendering
&&
this
._owner.IsInOnFormRender)
&&
((uniqueID
!=
null
)
&&
(uniqueID.IndexOf(
'
:
'
)
>=
0
)))
{
uniqueID
=
uniqueID.Replace(
'
:
'
,
'
$
'
);
}
return
((
"
__doPostBack('
"
+
uniqueID
+
"
','
"
)
+
Util.QuoteJScriptString(argument, forUrl)
+
"
')
"
);
}
这就是我们控件所
Render 的HTML 标记。 在他的onClick 事件上调用了__doPostBack('uniqueID','arg')函数,我们可以看到这个函数在页面的最下方定义好了。
<
input type
=
"
hidden
"
name
=
"
__EVENTTARGET
"
id
=
"
__EVENTTARGET
"
value
=
""
/
>
<
input type
=
"
hidden
"
name
=
"
__EVENTARGUMENT
"
id
=
"
__EVENTARGUMENT
"
value
=
""
/
>
function
__doPostBack(eventTarget, eventArgument) {
if
(
!
theForm.onsubmit
||
(theForm.onsubmit()
!=
false
)) {
theForm.__EVENTTARGET.value
=
eventTarget;
theForm.__EVENTARGUMENT.value
=
eventArgument;
theForm.submit();
}
}
通过上面的代码可以看到,
__doPostBack带有两个参数,eventTarget是标识将要引发页面PostBack的控件ID,eventArgument参数提供了在引发页面PostBack事件时所带的额外参数。当然这个函数被调用时,这两个参数的值将赋值给页面的两个隐含变量__EVENTTARGET和__EVENTARGUMENT,然后调用页面的submit方法提交页面表单。同时,我们可以通过Request.Form[“__EVENTTARGET”]获取得到引发页面PostBack的控件ID.除了GetPostBackEventReference 之外。 asp.net2.0 还提供了GetPostBackClientHyperlink 来通过 一个link 的 href
属性来引发postback。
2PostBack 引发之后, 如何在服务器端获取PostBack 的数据
LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) 里面的第一个参数的值是控件的UniqueID, 第2 个参数是一个
PostBackData 集合。 在我们的SimpleTextBox 控件里面, 它包含2 个键值对(__VIEWSTATE,
在这里需要注意的一点就是。 在Render 控件的过程当中, 需要把控件的UniqueID 作为需要PostBackData 的Input 标签的name 属性。否则即使实现了IPostBackDataHandler 接口 LoadPostData 方法也不会执行.如果我们的控件Render 多个Input 标签, 或者没有Render 任何Input 标签, 那么怎么办呢? LoadPostData 就无法执行了吗?当然不是了, 微软已经为我们想的很周到了, 我们只需要在控件的PreRender 方法里面注册一下就好了。
protected
override
void
OnPreRender(EventArgs e)
{
base
.OnPreRender(e);
this
.Page.RegisterRequiresPostBack(
this
);
}
这样的话无论PostBackData 的键集合里面是否包含控件的UniqueID, LoadPostData 方法都会照常执行。
RaisePostBackEvent 事件的执行也是一样
将控件的UniqueID 赋值给
应发事件的控件的Name属性。当然我们也可以显示申明要执行IPostBackEventHandler 接口。 重写OnLoad 方法如下
protected
override
void
OnLoad(EventArgs e)
{
base
.OnLoad(e);
this
.Page.RegisterRequiresRaiseEvent(
this
);
}