使用 .NET 框架轻松开发完美的 Web 窗体控件(一)

翻译|其它|编辑:郝浩|2005-06-16 10:23:00.000|阅读 1698 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


使用 .NET 框架轻松开发完美的 Web 窗体控件



本文假定您熟悉 Visual Basic .NET、C# 和 HTML

下载本文的代码: WebC.exe (274KB)

摘要 预建的自定义控件可以简化和加快应用程序的设计,并使您能够维护 UI 的一致性。但是,预先打包的控件可能很大,速度很慢,并且是特定于操作系统的。对于不愿意使用预先打包的控件的人来说,Visual Studio .NET 提供了类似于 Windows 窗体中的控件的 Web 窗体控件,其中包括标签和文本框,以及新增的 DataGrid 等,所有这些控件都可以进行自定义。

如果要设计自己的控件,您可以通过使用 .NET 框架所提供的可继承类来避免繁杂无味的工作过程,包括页生存周期、在调用之间维护状态以及浏览器检测。本文将对这些概念以及事件处理、呈现和客户端脚本进行介绍。


控件是一个很吸引人的概念。使用预先打包的 UI 功能时,可以更快、更廉价地完成设计,并能够在不同的应用程序之间保持更为一致的 UI。但这并不是它的所有特点。控件也可能会很大,与为特定任务而专门编写的代码相比,可能运行速度也要慢些。并且,基于 Windows 的控件结构如 Windows 窗体控件和早期的 ActiveX、OCX 和 VBX 控件,仅可以在 Windows 环境中运行 - 在当今几乎每天都有新的平台类型脱颖而出的异类 Internet 环境中,这很成问题。

为了能够跨平台运行,Microsoft 设计了Web 窗体结构 ASP.NET。使用 Visual Studio,您可以从工具箱中选择称为 Web 窗体控件的组件,并将它们放置在 ASPX 页上。然后,您可以设置该控件的属性,并使用任何支持 .NET 的语言编写代码,从而将其行为与其他控件相关联。这个过程被设计为与用 Visual Basic 编写应用程序类似,对于大多数程序员来说,这都是一个非常熟悉的过程。



图 1 页请求



客户端请求包含 Web 窗体控件的页时,ASP.NET 处理器将加载该页并在服务器上创建这些控件,如图 1 所示,然后执行该页的编程逻辑,将控件关联到一起。该过程结束时,每个控件都会向 ASP.NET 提供描述其当前外观的 HTML。这些 HTML 将被返回到客户端,并在浏览器中呈现。请在以下位置阅读有关ASP.NET Web 窗体的信息: ASP .NET:Web Forms Let You Drag and Drop Your Way to Powerful Web Apps。

Visual Studio 附带了一组通用的 Web 窗体控件,或多或少地与 Windows窗体中的可用控件组相对应。它包含标签和文本框等已为大家所熟悉的常用控件,还包含更新、更为复杂的控件如 DataGrid。

本文介绍了 .NET 框架为编写自己的 Web 窗体控件而提供的功能。由于我已经在 MSDN® Magazine 的 2002 年 4 月刊中介绍了控件的基本概念(方法、属性和事件),本文中,我将主要介绍 Web 窗体控件与基于 Windows 的控件之间的区别。之所以存在这些区别,主要是由于在相对简陋的浏览器运行库环境中运行,而不是在资源丰富的Windows 环境中运行。

.NET 对开发 Web 窗体控件的支持

.NET 框架中包含预先创建的软件类,这些类使得编写 Web 窗体控件变得相对简单。您需要理解 HTML 才可以生成控件所要求的输出,就像 Windows 窗体控件的设计者需要理解 Windows GDI 一样。但是,挂钩到 ASP.NET 页生存周期的例程、在多次调用之间维护状态的例程和检测宿主浏览器功能的例程(全部控件都具备的基础结构)已经为您编写好了。

您可以使用自己所选择的与 .NET 兼容的语言来编写控件,通过从自己选择的若干个 .NET 框架类继承来使用预先创建的基础结构。这些基类大致对应于 Windows 窗体中的类。但是,常见的情况是,Microsoft 使用了同一个名称来在看上去类似的环境中指代不同的事物,因此,必须谨慎从事,并阅读附属细则。下面介绍开发 Web 窗体控件的五种方法。

第一种选择是从 System.Web.UI.Control 派生,该类是所有 Web 窗体控件的基类。它参与 ASP.NET 页呈现过程的所有生存周期事件。文档中指出该类没有任何特定于用户界面的功能,虽然它存在于 System.Web.UI 命名空间中。我有不同意见。它包含一个 Render 方法(将在下一节对其进行介绍),控件使用该方法来发出要在浏览器中显示的 HTML。它比我要介绍的下一个类具有更少的内置 UI 属性;例如,它没有 Width、Height、ForeColor、BackColor 和 Font,但如果您一定要使用它来生成 UI,实现起来仍是非常容易的。由于省略了以上元素,它更为轻型化,但由此所造成的差异微乎其微。如果您不关注它所省略的任何功能,使用它作为基类完全没有问题。

您的下一个选项是从 System.Web.UI.WebControls.WebControl 派生,该类派生自 System.Web.UI.Control。这是一个添加了基本用户界面属性的控件。当您生成新的 Web 控件库项目时,Visual Studio 会自动使用它作为基类。如果您想要得到像大多数控件一样提供用户界面的控件,您可能应当从这里开始。

您还可以从现有的 Web 窗体控件入手,可以是 Visual Studio 附带的控件,或者从第三方购买的控件。此时,您需要使用 .NET 继承机制从现有控件派生自己的控件。您需要重用现有功能中自己需要的部分,重写要更改的部分,并添加要使控件具备的任何附加功能。在我以前的文章中,曾经介绍了如何使用 Windows 窗体文本框控件来完成以上任务。针对 Web 窗体控件完成该任务与此完全相同,这里不再重复介绍。

另一个选项是设计一个包含其他控件的控件。在 Windows 窗体中,它称为用户控件,但是在 Web 窗体中,它称为复合控件。您可以为自己的基类选择以上所介绍的三种继承方案中的任一种。不幸的是,Web 窗体不像 Windows 窗体一样支持添加子控件。因此,必须在代码中手动创建和定位子控件。这并不困难,因此这里不作讨论。但是,我发现这一省略颇为令人吃惊。

最后,您可以选择创建用户控件。以上所讨论的每个控件都是完全编译的 .NET 程序集。它们可用于 Visual Studio 工具箱和设计器,并可以保存在全局程序集缓存 (GAC) 中,因此无需为每个要使用它们的客户端使用一个单独的副本。Web 窗体提供了另外一种生成可重用控件包的方法(用户控件)。像您在 Windows 窗体中看到的用户控件一样,Web 窗体用户控件是通过在 Visual Studio 设计器中将其他控件放置到设计图面上来生成的。但是,与 Windows 窗体用户控件不同,这种用户控件是一个 HTML 页,而不是已编译的程序集,因此不能保存到 GAC 或 Visual Studio 工具箱中,而且,也不能在 Visual Studio 设计器中显示其外观。因此,我认为它的有用性远不如我所介绍的其他类型的 Web 窗体控件。我怀疑它之所以存在,是因为复合 Web 窗体控件中缺少设计器支持。


简单的自定义控件

在学习或者讲解新软件时,我总会从我所能想到的最简单的示例入手。这是一个标签控件,它包含一个称为 Text 的属性,该属性是标签所显示的字符串,它还包含一个称为 ForeColor 的属性,即该文本字符串的颜色(参见图 2)。



图 2 标签控件



我首先在 Visual Studio 中生成了该项目,然后从 New Project 对话框中选择了 Web Control Library,如图 3 所示。向导生成了一个项目,该项目包含一个派生自 System.Web.UI.WebControls.WebControl 的新类。向该类中添加方法和属性与向任何其他 .NET 类添加方法和属性完全相同。实际上,系统提供的基类已经包含了本示例中所使用的称为 Text 和 ForeColor 的属性。



图 3 生成项目


就像我说的一样,这非常简单。基本上是这样的。理解自定义 Web 窗体控件的关键在于 Render 方法,该方法在概念上与 Windows 窗体 OnPaint 方法相同,区别仅在于前者发出 HTML,而后者则发出 GDI 调用。当 ASP.NET 服务器框架为响应用户请求而汇编 Web 窗体页时,它将创建页上列出的控件,设置这些控件的属性和持久性数据,然后调用它们的各个 Render 方法。框架实际上是告诉控件:“你是活动的,并正处于预期的状态。你需要告诉我你的外观,因为我没有别的办法来了解。”Web 窗体控件的作者会在 Render 方法中放入一些代码,以发出 HTML,告知浏览器如何根据控件的当前状态和属性,以及与控件有关的环境中的任何其他信息来显示控件的外观。

Web 窗体控件的作者需要了解 HTML,这是因为环境提供的相关摘要信息很少。以下是指定文本颜色的 HTML:

<span style="color:green;">
Here is some text
</span>

为了生成这些 HTML,我编写了图 4 中所示的代码。大多数读者都告诉我他们希望源代码使用 Visual Basic 来编写;为了照顾 C# 读者,我使用 Visual Basic 和 C# 两种语言编写了可下载的示例代码。

当 ASP.NET 框架调用控件的 Render 方法时,将传递一个 System.Web.UI.HtmlTextWriter 类型的对象。这在概念上类似于 OnPaint 方法在 Windows 窗体控件中收到的 System.Windows.Forms.PaintEventArgs 的 Graphics 成员。两者都代表到框架的连接,该框架将输出定位到其相应的位置。HtmlTextWriter 包含的方法、属性和常数使得您的控件能够将 HTML 发送到将被发送到客户端浏览器的输出页上。在示例代码中,我首先调用了方法 AddStyleAttribute,该方法在内部创建一个称为 style 的 HTML 属性,将其值设置为控件所继承的 ForeColor 属性的值,然后将其添加到内部缓冲区。可以通过对 AddStyleAttribute 方法的附加调用向缓冲区添加 style 属性的附加值;通过调用 AddAttribute 方法,可以添加其他属性,当然,在本例中,并不需要这么做。

接着,我调用了方法 RenderBeginTag,指定文本中要显示的 HTML 标记的名称,本例中为“span”。该调用从内部缓冲区中提取任何属性(此处为 style),将它们放置到标记中,然后写入 HTML输出流中。这两个调用生成了第一行 HTML:

<span style="color:green;">

接下来,为了编写标签的文本,我调用了方法 HtmlTextWriter.Write,以传递控件的内部文本字符串。该方法将文本字符串 verbatim 传递到 HTML 输出流中,从而生成了第二行:

Here is some text

为了关闭 标记,我调用了 HtmlTextWriter.RenderEndTag。这导致编写器读回最后一个打开的标记,并发出该标记的关闭标记,在本例中为 ,以作为最后一行 HTML。
该对象包含用于执行输出的其他方法,这些方法能够提供更为精细的控件,但较为复杂。为简单起见,我将在本文的其余部分中沿用前面的方法。





图 5 向工具箱中添加新的控件


 


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP