在ASP.NET 1.1中,经常需要以模态的方式显示对话框,并向其传递参数,同时在对话框关闭时获取返回值。在传统的ASP时期,通常会使用JavaScript在客户端完成这项任务,并将包含返回值的表单提交到后端程序。现在,ASP.NET已成为B/S架构中的主要工具,希望将这种方式改为ASP.NET 1.1。
在ASP.NET中,使用事件模型来快速编程。事件模型的本质是表单的提交。所有的事件设置在页面渲染时都会被转换为JavaScript来提交表单。通常,在客户端HTML中可以看到以下代码段:
<input type="hidden" name="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" value="dDw4MTc2ODI0Mzc7Oz4Sp8vtufeHPnCSpIk8Obsuj84lVg==" />
<script language="javascript" type="text/javascript">
<!--
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
theform = document.Form1;
}
else {
theform = document.forms["Form1"];
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
// -->
</script>
函数“__doPostBack”是提交事件到服务器的函数。它使用两个隐藏域来记录事件源和参数。当"__EVENTTARGET"被填充为“Button2”并提交到服务器时,它可以触发服务器控件“Button2”的事件。使用这个函数来触发包含代码的事件,以从模态对话框中接收返回值。以下是代码示例:
private void Button1_Click(object sender, System.EventArgs e)
{
string strScript =
@"
<script defer>
+
"
var strReturn = window.showModalDialog('list.aspx','desc','dialogWidth:423px;dialogHeight=355px');
+
"
__doPostBack('Button2',strReturn);"
+
"
</script>";
if (!this.IsClientScriptBlockRegistered("OpenDialogScript"))
this.RegisterStartupScript("OpenDialog",strScript);
}
在调用页面中,添加了一个ID为“Button2”的LinkButton。顺便说一句,最好不要使用Button或ImageButton来生成事件,因为它无法在客户端生成“__doPostBack”函数。
在list.aspx的服务器代码中,当首次加载页面时,它应该获取客户端的window.dialogArguments,并且当它不为空时,必须提交到服务器。如下所示:
private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
string strScript =
@"
<script defer> if(window.dialogArguments!=null) __doPostBack('',window.dialogArguments); </script>"
;
if (!this.IsClientScriptBlockRegistered("GetArgumentScript"))
this.RegisterStartupScript("GetArgumentScript",strScript);
}
else
{
if (ViewState["ORDERBY"] == null)
{
ViewState["ORDERBY"] = Request["__EVENTARGUMENT"];
BindData();
}
}
}
然后,可以在调用页面中轻松地接收模态页面的返回值:
private void Button2_Click(object sender, System.EventArgs e)
{
TextBox1.Text = Request["__EVENTARGUMENT"];
}
实际上,有一个通用的方法来获取值。在调用页面(WebForm1.aspx)中,可以直接使用form1.submit方法。
private void Button1_Click(object sender, System.EventArgs e)
{
string strScript =
@"
<script defer>
+
"
var strReturn = window.showModalDialog('list.aspx','desc','dialogWidth:423px;dialogHeight=355px');
+
"
Form1.action='WebForm1.aspx?src=MODAL&value='+strReturn; Form1.submit();"
+
"
</script>";
if (!this.IsClientScriptBlockRegistered("OpenDialogScript"))
this.RegisterStartupScript("OpenDialog",strScript);
}
因此,在Page_Load事件中,应该像下面这样过滤这个请求:
private void Page_Load(object sender, System.EventArgs e)
{
if (Request["src"] != null && Request["src"].toUpper() == "MODAL")
{
string strReturnValue = Request["value"];
// 处理返回值的代码在这里...
}
}
最后一点,如果在模态页面中提交表单,它将打开一个新页面来处理请求。要解决这个问题,可以设置属性smartNavigation="True",这个选项将在iframe中提交表单。另一种方法是,在HTML文本的
... 部分中编写以下代码:
<HTML><br> <HEAD><br> ....<br> <base target=_self><br>
</HEAD>
<br> ....<br>
</HTML>
在list.aspx中,还展示了如何在DataGrid中选择多行复选框以及自定义分页的简单方法。