自定义对话框控件






4.70/5 (21投票s)
关于在 ASP.NET 2.0 中创建模板化控件的文章。
引言
本文介绍了一个漂亮的、类似 Office 界面的 ASP.NET 2.0 对话框控件。我创建此控件是为了练习在 .NET 2.0 中开发模板化控件。代码使用了自定义设计器,以及 `System.Web.UI` 命名空间中新的 GetWebResourceUrl
方法。该控件是创建具有 AJAX 功能的网页时的有用补充,而且外观也非常漂亮。
DialogBox 类
类图。点击放大。 |
|
该控件还重写了基类的 OnInit
方法和 Tagkey
属性,以便渲染必要的 JavaScript,并且 Tagkey
属性确保我们的控件被渲染为 <div>
标签。
我选择让我的 DialogClass
继承自 CompositeControl
类。CompositeControl
类是 .NET 2.0 中的一个新类,专门用于创建带有子控件的自定义控件。它负责处理诸如确保当控件使用者尝试使用 FindControl
方法和 Controls
集合时创建子控件等问题。它还实现了 INamingContainer
接口,确保所有子控件都具有唯一的 ClientID。
模板化控件的特别之处
如果您使用过 ASP.NET,您可能已经使用过模板化控件,但可能不知道。DataGrid
、Repeater
或 DataList
控件是模板化控件的典型例子。模板化控件允许开发人员在模板化控件内部渲染自定义 HTML 甚至自己的 ASP.NET 控件。创建模板化控件分两步进行:
- 公开一个类型为
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;} } }
- 从重写的
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 - 第一个版本。