65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (12投票s)

2004年12月1日

3分钟阅读

viewsIcon

132962

downloadIcon

802

一对服务器控件,DialogOpener 和 DialogCloser,您可以将它们放置在 Web 表单上,以便打开一个对话框,并在对话框关闭时,触发您选择的主窗体服务器事件。

引言

通常在使用 ASP.NET 编程时,您希望弹出一个对话框窗口来请求某种用户输入。当用户完成对话框并关闭它时,您希望主窗体触发一个服务器事件,该事件执行某种刷新或其他操作。令人惊讶的是,这项任务并非看起来那么容易,而且 Google 搜索会找到大量令人困惑的信息。您最终编写的代码可能比您需要的要多得多。经过一些试验,我认为我找到了一种相当简洁和整洁的方式来完成此操作,因此为了避免再次这样做,我将打开和关闭对话框的代码封装在一对服务器控件中。

本文介绍了一对服务器控件,DialogOpenerDialogCloser,使您能够快速设置一个对话框,该对话框可以打开、接收用户输入、关闭,并在主窗体上触发您选择的事件。

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 事件,并且您的事件处理程序代码将运行。

结论

这篇短文向您展示了如何创建一对有用的服务器控件,您可以将它们拖放到一对窗体上以处理对话框的打开和关闭,并在对话框关闭时在主窗体上调用服务器事件。希望这能让您避免像我一样搜索答案的麻烦!

© . All rights reserved.