以前做过一个项目中要求当填写联系人的时候,点击 一个按钮后弹出一个子窗口,选中子窗口中的联系人后,将选中的联系人的值填充到父窗口来,当时以为很简单,但一做起来就发现不是很好下手,最近,当我看到一篇写ASP.NET的回传机制的文章后,终于有一点头绪了,于是就做了一个类似的小例子,就是在一个窗口中点击一个按钮后弹出一个子窗口然后将选中的子窗口的值填充到父窗口的一个TextBox中,详细说明如下:
1.首先是父窗口中我只定义了一个Button和一个TextBox,具体代码如:(父窗口叫WebForm1.aspx)
下面是.aspx页面上的代码:
<%
@ Page language
=
"
c#
"
Codebehind
=
"
WebForm1.aspx.cs
"
AutoEventWireup
=
"
false
"
Inherits
=
"
Wtest.WebForm1
"
%>
<!
DOCTYPE HTML PUBLIC
"
-//W3C//DTD HTML 4.0 Transitional//EN
"
>
<
HTML
>
<
HEAD
>
<
title
>
WebForm1
</
title
>
<
meta content
=
"
Microsoft Visual Studio .NET 7.1
"
name
=
"
GENERATOR
"
>
<
meta content
=
"
C#
"
name
=
"
CODE_LANGUAGE
"
>
<
meta content
=
"
JavaScript
"
name
=
"
vs_defaultClientScript
"
>
<
meta content
=
"
http://schemas.microsoft.com/intellisense/ie5
"
name
=
"
vs_targetSchema
"
>
<
script type
=
"
text/javascript
"
>
function OpenWindow()
...
{
window.open('test.aspx','','height=200,width=200,left=200,top=150,locatinotallow=no,menubar=no,resizable=false,scrollbars=yes,status=no,titlebar=no,toolbar=no');
}
function init(userName)
...
{
__doPostBack("userName",userName);
}
function DisplayName(para)
...
{
document.getElementById('<%= TextBox1.ClientID%>').value = para;
}
</
script
>
</
HEAD
>
<
body MS_POSITIONING
=
"
GridLayout
"
>
<
form id
=
"
Form1
"
runat
=
"
server
"
>
&
nbsp;
<
input id
=
"
Button1
"
style
=
"
Z-INDEX: 101; LEFT: 216px; POSITION: absolute; TOP: 152px
"
onclick
=
"
OpenWindow();
"
type
=
"
button
"
value
=
"
打开
"
name
=
"
btnOk
"
runat
=
"
server
"
>
<
asp:TextBox id
=
"
TextBox1
"
style
=
"
Z-INDEX: 102; LEFT: 272px; POSITION: absolute; TOP: 152px
"
runat
=
"
server
"
></
asp:TextBox
></
form
>
</
body
>
</
HTML
>
这个父窗口(WebForm1.aspx.cs)的后台CS里面的代码如下:
using System;
using
System.Collections;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Web;
using
System.Web.SessionState;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.HtmlControls;
namespace
Wtest
...
{
/**//// <summary>
/// WebForm1 的摘要说明。
/// </summary>
public class WebForm1 : System.Web.UI.Page
...{
protected System.Web.UI.HtmlControls.HtmlInputButton Button1;
protected System.Web.UI.WebControls.TextBox TextBox1;
private void Page_Load(object sender, System.EventArgs e)
...{
// 在此处放置用户代码以初始化页面
if (Request["__EVENTTARGET"]=="userName")
...{
string userName = Request["__EVENTARGUMENT"].ToString();
Page.RegisterStartupScript("DisplayName","<script language='javascript'>DisplayName('"+ userName +"');</script>");
}
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
...{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
...{
this.Button1.ServerClick += new System.EventHandler(this.Button1_ServerClick);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void Button1_ServerClick(object sender, System.EventArgs e)
...{
}
}
}
2.然后就是弹出的子窗口的代码(test.aspx):
首先是页面上的代码:
<% @ Page language =
"
c#
"
Codebehind
=
"
test.aspx.cs
"
AutoEventWireup
=
"
false
"
Inherits
=
"
Wtest.test
"
%>
<! DOCTYPE HTML PUBLIC
"
-//W3C//DTD HTML 4.0 Transitional//EN
"
>
< HTML
>
< HEAD
>
< title
>
test
</
title
>
< meta content
=
"
Microsoft Visual Studio .NET 7.1
"
name
=
"
GENERATOR
"
>
< meta content
=
"
C#
"
name
=
"
CODE_LANGUAGE
"
>
< meta content
=
"
JavaScript
"
name
=
"
vs_defaultClientScript
"
>
< meta content
=
"
http://schemas.microsoft.com/intellisense/ie5
"
name
=
"
vs_targetSchema
"
>
< script type
=
"
text/javascript
"
>
function Close()
... {
window.close();
window.opener.focus();
return false;
}
function setName(userName)
... {
window.opener.init(userName);
Close();
}
</ script
>
</ HEAD
>
< body MS_POSITIONING
=
"
GridLayout
"
>
< form id
=
"
Form1
"
method
=
"
post
"
runat
=
"
server
"
>
< table cellSpacing
=
"
0
"
cellPadding
=
"
0
"
width
=
"
95%
"
align
=
"
center
"
>
< tr
>
< td align
=
"
center
"
>
< table width
=
"
80%
"
border
=
"
1
"
cellpadding
=
"
0
"
cellspacing
=
"
0
"
bgcolor
=
"
#f6f6f6
"
>
< tr
>
< td height
=
"
60
"
>
< asp:listbox id
=
"
ListBox1
"
Width
=
"
100%
"
runat
=
"
server
"
Height
=
"
176px
"
>
< asp:ListItem Value
=
"
hekai
"
>
何凯
</
asp:ListItem
>
< asp:ListItem Value
=
"
wuyu
"
>
吴禹
</
asp:ListItem
>
< asp:ListItem Value
=
"
gaochao
"
>
高超
</
asp:ListItem
>
< asp:ListItem Value
=
"
zs
"
>
张松
</
asp:ListItem
>
< asp:ListItem Value
=
"
dc
"
>
蠹虫
</
asp:ListItem
>
< asp:ListItem Value
=
"
zhouXX
"
>
周星星
</
asp:ListItem
>
< asp:ListItem Value
=
"
XiMu
"
>
西木
</
asp:ListItem
>
</ asp:listbox
></
td
>
</ tr
>
</ table
>
</ td
>
</ tr
>
< tr
>
< td height
=
"
36
"
align
=
"
center
"
>
< asp:button id
=
"
Button1
"
runat
=
"
server
"
Text = "
确定
"
></
asp:button
>
</ td
>
</ tr
>
</ table
>
</ form
>
</ body
>
</ HTML
>
接着是该子窗口的后台CS代码:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace Wtest
... {
/**//// <summary>
/// test 的摘要说明。
/// </summary>
public class test : System.Web.UI.Page
...{
protected System.Web.UI.WebControls.ListBox ListBox1;
protected System.Web.UI.WebControls.Button Button1;
private void Page_Load(object sender, System.EventArgs e)
...{
// 在此处放置用户代码以初始化页面
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
...{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
...{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void Button1_Click(object sender, System.EventArgs e)
...{
Page.RegisterStartupScript("SetLinkMan","<script language='javascript'>setName('"+ ListBox1.SelectedValue +"');</script>");
}
}
}
我再来详细的说明一下上面的代码的意思:
其实这个例子的原理是利用了ASP.NET的回发机制做的(doPostBack),我们找到,在一个aspx页面中只要有回发
控件,则在生成了aspx页面中产生出这样子一段代码:
< input type = " hidden
"
name
=
"
__EVENTTARGET
"
value
=
""
/>
< input type = "
hidden
"
name
=
"
__EVENTARGUMENT
"
value
=
""
/>
< 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 >
我们正是利用了这样一个机制,来将弹出窗口的值传回到父窗口中来,其实在子窗口中,我们只是
将获取到的值利用window.opener.init("要传送的值")这个方法将值发到父窗口中,但实际是回发后父窗口
并没有马上获取到这个从其子窗口传回来的值,在这里,我们是利用了一个__doPostBack()函数来让
父窗口获取得到这个值的,因为只要有回发操作发生,都会调用这个__doPostBack()函数,正是利用
ASP.NET的这一机制,使我们可以获取到从子窗口传回来的值。
注意:我刚开始做的时候发现页面上并没有__doPostBack()这个方法,后来google一下才知道必须有
能够触发回发机制产生的控件才会产生该方法,我当时的父窗口的Button是用的客户端控件,所以
不会产生doPostBack函数,因为服务器端的Button可以触发回发产生,所以我让这个Button的属性
设置为runat='server',于是就可以产生回发了,但是如果你页面上没有button而你又想让页面回发,其实
还有一种方法就是 将某个服务器控件的AutoPostBack设置为True就可以了,比如说一个TextBox想这样
设置以后也可以产生回发。