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

自定义对话框控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (21投票s)

2005年10月21日

CPOL

6分钟阅读

viewsIcon

224554

downloadIcon

3067

关于在 ASP.NET 2.0 中创建模板化控件的文章。

Sample Image

引言

本文介绍了一个漂亮的、类似 Office 界面的 ASP.NET 2.0 对话框控件。我创建此控件是为了练习在 .NET 2.0 中开发模板化控件。代码使用了自定义设计器,以及 `System.Web.UI` 命名空间中新的 GetWebResourceUrl 方法。该控件是创建具有 AJAX 功能的网页时的有用补充,而且外观也非常漂亮。

DialogBox 类

类图。点击放大。

DialogBox 类具有以下属性:

  • Resizable - 确定用户是否可以调整控件的大小
  • Moveable - 确定用户是否可以移动控件
  • InitialDisplayStyle - 一个 enum,描述了页面加载时控件的状态
  • Text - 对话框的标题

DialogBox 类有两个方法:

  • CreateChildControls - 从基类重写。复合控件的所有子控件都应在此方法中创建。运行时调用此方法来呈现控件。
  • GetDesignTimeHtml - 一个内部方法,由设计器用于在设计时强制正确呈现控件。

该控件还重写了基类的 OnInit 方法和 Tagkey 属性,以便渲染必要的 JavaScript,并且 Tagkey 属性确保我们的控件被渲染为 <div> 标签。

我选择让我的 DialogClass 继承自 CompositeControl 类。CompositeControl 类是 .NET 2.0 中的一个新类,专门用于创建带有子控件的自定义控件。它负责处理诸如确保当控件使用者尝试使用 FindControl 方法和 Controls 集合时创建子控件等问题。它还实现了 INamingContainer 接口,确保所有子控件都具有唯一的 ClientID。

模板化控件的特别之处

如果您使用过 ASP.NET,您可能已经使用过模板化控件,但可能不知道。DataGridRepeaterDataList 控件是模板化控件的典型例子。模板化控件允许开发人员在模板化控件内部渲染自定义 HTML 甚至自己的 ASP.NET 控件。创建模板化控件分两步进行:

  1. 公开一个类型为 ITemplate 的公共属性,如下所示:
            public class DialogBox : System.Web.UI.WebControls.CompositeControl
            {        
                private ITemplate containerTemplate;
                private Control containerControl;
    
                [Browsable(false),
                PersistenceMode(PersistenceMode.InnerProperty)]
                public virtual ITemplate ItemTemplate
                {
                    get {return containerTemplate;}
                    set {containerTemplate = value;}
                }
            }
  2. 从重写的 CreateChildControls 方法中创建模板。
                containerControl = new Control();
                if (ItemTemplate != null)
                {
                    ItemTemplate.InstantiateIn(containerControl);
                }
                else
                {
                    containerControl.Controls.Add(new LiteralControl(Text));
                }

    else - 代码块仅用于在用户创建对话框模板之前,当控件添加到页面时显示某些内容。如果未创建模板,控件将在内容区域渲染标题。

使用 GetWebResourceUrl

ASP.NET 2.0 中的一个很酷的新功能是能够创建编译到控件本身的资源。ASP.NET 2.0 提供了一个新的 HTTP 处理程序,“WebResource.axd”。这有点类似于 Trace.axd 处理程序,但该处理程序可用于访问您控件项目中的任何静态资源,例如图像、JavaScript 文件、声音或您想编译到项目中的任何其他内容。这个新功能极大地简化了控件开发者的工作,因为外部文件的版本管理变得更加容易。使用 GetWebResourceUrl 有点棘手,涉及三个步骤。

首先,将您的资源添加到项目中。在“属性”窗格中,将文件的 **生成操作** 设置为 **嵌入的资源**。

其次,将您的资源添加到项目的 AssemblyInfo.cs 文件中,如下所示:

[assembly: WebResource("WebControls.Resources.header_decoration.gif", "image/gif")]

WebResource 属性的第一个参数是资源的完全限定名称。MSDN 文档并未提及这一点,但您必须在文件名 (header_decoration.gif) 前加上程序集名称 (WebControls) 和它所在的文件夹 (Resources)。第二个参数是您的资源应返回给浏览器的 MIME 类型。

第三,向您的页面添加代码以生成访问资源所需的特殊 URL。

imgHeaderDeco = new Image();
imgHeaderDeco.ImageUrl = Page.ClientScript.GetWebResourceUrl(
                         typeof(DialogBox), 
                         "WebControls.Resources.header_decoration.gif");

在网页上生成的输出应类似于:

<img src="https://codeproject.org.cn/WebSite2/WebResource.axd?
   d=E1Khv7nbIwG5fSPcsXnzTP4Bukco5S0XUA0FBsHzjTskoXfzMVF14ZAlK7adsv
   PsJgALtyt5nqpSESM7tDVIZA2&t=632651830942047145" />

设计器

DialogDesigner 类继承自 CompositeControlDesigner 类。基类是 .NET 2.0 的另一个新添加项,它使得创建模板化控件比 .NET 框架的早期版本更容易。设计器对于获得控件的正确设计时行为是必需的。

使用代码

使用代码非常简单;只需将控件添加到工具箱,将其拖到网页上,即可运行。要在设计视图中设置模板,请点击对话框右上角附近的小箭头,然后选择“编辑模板”。或者,在源视图中,输入类似以下内容(以粗体标出):

        <fwc:DialogBox ID="DialogBox1" runat="server" Height="33px" 
              Width="202px" Resizable="True" Text="A custom dialogbox" 
              InitialDisplayState="ShowingDialog">
            <ItemTemplate>
                <center><b>Hello, world!</b></center>
            </ItemTemplate>
        </fwc:DialogBox>
        <a href="javascript:ShowDLG('<%=DialogBox1.ClientID%>'">Show dialog</a>
        <a href="javascript:HideDLG('<%=DialogBox1.ClientID%>'">Hide dialog</a>

ItemTemplate 标签内,您可以输入任何有效的 HTML 以及 ASP.NET 服务器控件。**注意:** 如果您使用 ASP.NET 服务器控件,它们可以通过对话框实例的 FindControl 方法重新找到。它们在回发期间也会保持状态。从上面的代码片段中您还可以看到,对话框 JavaScript 有两个方法:ShowDLG 用于显示对话框,HideDLG 用于隐藏对话框。

进一步发展

目前,该控件在回发之间不保留状态位置或显示状态。我的目的是在 AJAX 页面上使用该控件,因此回发不是问题。但是,我正在考虑在将来的版本中实现它。

该控件已在 IE 6 和 Mozilla 1.5 上进行了测试并运行正常。在 Mozilla 中,它无法 100% 正确呈现,但我还没有费心去研究它。

如果我有时间,我想添加一些更多的 JavaScript 功能,特别是用 JavaScript 代码操作控件,设置标题,移动它,在屏幕中央打开它等等。

我才刚开始研究皮肤,所以目前该控件在这方面不太灵活。

另外,我对设计器不太满意。它能正确显示控件,但由于它在设计器中始终以打开状态呈现,因此在设计视图中可能会阻碍访问其他控件。一种解决方案是向设计器类添加一个操作动词(显示/隐藏控件),并根据操作动词的选择来呈现正确的 HTML 或块(例如,类似于 ASP.NET 1.0 下 UserControls 的呈现方式)。

如果您希望在将来的版本中看到某个功能,请 告知我,我会尽力而为。

关注点

如果您对设计自定义控件感兴趣,我推荐阅读 Nikhil Kohtari 的书 Developing Microsoft ASP.NET Server Controls and Components。这本书对于如何创建自定义控件来说是一本很好的读物。

历史

  • 2005/10/18 - 第一个版本。
© . All rights reserved.