打开对话框,关闭时在主表单上触发服务器事件






4.74/5 (12投票s)
2004年12月1日
3分钟阅读

132962

802
一对服务器控件,DialogOpener 和 DialogCloser,您可以将它们放置在 Web 表单上,以便打开一个对话框,并在对话框关闭时,触发您选择的主窗体服务器事件。
引言
通常在使用 ASP.NET 编程时,您希望弹出一个对话框窗口来请求某种用户输入。当用户完成对话框并关闭它时,您希望主窗体触发一个服务器事件,该事件执行某种刷新或其他操作。令人惊讶的是,这项任务并非看起来那么容易,而且 Google 搜索会找到大量令人困惑的信息。您最终编写的代码可能比您需要的要多得多。经过一些试验,我认为我找到了一种相当简洁和整洁的方式来完成此操作,因此为了避免再次这样做,我将打开和关闭对话框的代码封装在一对服务器控件中。
本文介绍了一对服务器控件,DialogOpener
和 DialogCloser
,使您能够快速设置一个对话框,该对话框可以打开、接收用户输入、关闭,并在主窗体上触发您选择的事件。
DialogOpener
以下是 DialogOpener
控件的代码
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web;
namespace ExWebCtlLib
{
[DefaultProperty("Text"), ToolboxData("<ExWebCtlLib:DialogOpener
runat=server></WebCtlLib:DialogOpener>")]
public class DialogOpener : System.Web.UI.WebControls.WebControl,
IPostBackEventHandler
{
[Bindable(true)]
public event EventHandler DialogClosed
{
add
{
dialogClosed += value;
}
remove
{
dialogClosed += value;
}
}
private event EventHandler dialogClosed;
[Bindable(true), Category("Appearance"), DefaultValue("")]
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
private string text = "Open Dialog";
[Bindable(true), Category("Appearance"), DefaultValue("")]
public string DialogName
{
get
{
return dialogname;
}
set
{
dialogname = value;
}
}
private string dialogname = "Dialog";
[Bindable(true), Category("Appearance"), DefaultValue(true)]
public bool Scrollbars
{
get
{
return scrollbars;
}
set
{
scrollbars = value;
}
}
private bool scrollbars = true;
[Bindable(true), Category("Appearance"), DefaultValue("")]
public string DialogPagePath
{
get
{
return dialogPagePath;
}
set
{
dialogPagePath = value;
}
}
private string dialogPagePath = "";
[Bindable(true), Category("Appearance"), DefaultValue("")]
public string DialogParam
{
get
{
if( ViewState[ this.ID + "DialogParam" ] == null )
return dialogParam;
else
return (string)ViewState[ this.ID + "DialogParam" ];
}
set
{
dialogParam = value;
ViewState[ this.ID + "DialogParam" ] = value;
}
}
private string dialogParam = "-1";
protected override void Render(HtmlTextWriter output)
{
string url = HttpContext.Current.Request.ApplicationPath + "/" +
DialogPagePath + @"?PostBackEventReference=" +
Page.Server.UrlEncode( Page.GetPostBackEventReference(this) ).Replace(
"'", "%27" ) + @"&DialogParam=" + DialogParam;
string height = Height.Value.ToString();
string width = Width.Value.ToString();
string scrollbars = Scrollbars ? "yes" : "no";
output.Write( @"<input id=""ExFxDialogOpener"" type=""button""
value=""" + Text + @""" class=""" + CssClass + @"""
onclick=""javascript:OpenDialog('" + url + "', '" +
DialogName + "', " + height + ", " + width + ", '" +
scrollbars + "' " + @" );"">" );
}
public void RaisePostBackEvent(string eventArgument)
{
if( dialogClosed != null )
dialogClosed( this, new EventArgs() );
}
}
}
代码大多非常简单,只是一些带有 getter 和 setter 的简单属性。有趣的属性是 DialogClosed
事件属性。当对话框关闭时,此事件将在表单上触发。现在看看 URL 的构造,特别是 PostBackEventReference
参数。该控件生成的 HTML 看起来像这样,具体取决于控件的精确设置
<input id="ExFxDialogOpener" type="button" value="Image Gallery"
class="Button" onclick="javascript:OpenDialog(
'/html/Forms/Fx/ImageGallery.aspx?PostBackEventReference=
__doPostBack(%27_ctl15%24ImageGalleryOpener%27%2c%27%27)
&DialogParam=SelectImage', 'Dialog', 456, 580, 'yes' );">
PostBackEventReference
作为 URL 参数传递给对话框。我们将在对话框中使用该信息在关闭时触发服务器事件。
脚本调用 JavaScript 函数 OpenDialog(...)
。您需要通过使用 RegisterClientScript
在主窗体中注册它,或者修改控件以直接调用 window.open
,以确保页面中存在 OpenDialog
脚本。以下是 OpenDialog
的脚本。
function OpenDialog( url, name, height, width, scrollbars )
{
if( scrollbars == null )
scrollbars = "yes";
var top = (screen.height - height) / 2;
var left = (screen.width - width) / 2;
window.open( url, name, "width = " + width + ",
height = " + height + ", menubar = no,
scrollbars = " + scrollbars + ", toolbar = no,
location = no, directories = no, resizable = no,
top = " + top + ", left = " + left );
(由于我们的商店中有标准的 JavaScript 注册模板,OpenDialog
在我们的页面上始终可用,这就是它没有包含在 DialogOpener
代码中的原因。)
DialogCloser
DialogCloser
控件生成必要的 JavaScript,以关闭对话框并在主窗体上触发服务器事件。它通过使用 DialogOpener
读取我们在 URL 中传递的 PostBackEventReference
并构建所需的 JavaScript 来实现此目的。
以下是 DialogCloser
的代码
public class DialogCloser : System.Web.UI.WebControls.WebControl
{
public void Close()
{
if( HttpContext.Current.Request[ "PostBackEventReference" ] == null )
Page.RegisterStartupScript("__close", "<script>window.close();</script>");
else
{
string script = String.Format("<script>window.opener.{0};
window.close();</script>", HttpContext.Current.Request[
"PostBackEventReference" ] );
Page.RegisterStartupScript( "__close", script );
}
}
}
以下是在调用 DialogCloser.Close
时注册的 JavaScript 的示例
<script>
window.opener.__doPostBack('_ctl15$ImageGalleryOpener','');
window.close();
</script>
编译控件
要编译控件,只需在您自己的服务器控件库中创建几个新的服务器控件类。如果您没有服务器控件库,请创建一个类型为“类库”的新项目,放入代码,编译,然后右键单击您的工具箱,单击“添加/删除项目”,然后浏览到您刚刚创建的 .dll。单击“确定”,两个控件将出现在您的工具箱中。
使用控件
使用这些控件很容易。创建两个 aspx 页面。一个将是主窗体,另一个将是对话框。将 DialogOpener
拖放到主窗体上并打开“属性”表。将 DialogPagePath
属性设置为对话框页面的路径和名称。双击 DialogClosed
事件并编写您希望在对话框关闭时运行的代码。
将 DialogCloser
控件拖放到对话框窗体上。在对话框代码的某个位置,当您希望对话框关闭时,编写以下行
DialogCloser.close();
运行主窗体。单击 DialogOpener 按钮。关闭对话框。主窗体上将调用 DialogClosed
事件,并且您的事件处理程序代码将运行。
结论
这篇短文向您展示了如何创建一对有用的服务器控件,您可以将它们拖放到一对窗体上以处理对话框的打开和关闭,并在对话框关闭时在主窗体上调用服务器事件。希望这能让您避免像我一样搜索答案的麻烦!