在 Web 部件应用程序中,主要的用户界面(UI)由 Web 页面区域的 ASP.NET 服务器控件所组成,Web 页面拥有公共的 UI 以及派生自 WebPartZoneBase
类的合成控件。这些来自于 Web 部件应用程序的主 UI 中的服务器控件的能力被定义在 WebPart
基类中,但是这对于你对派生控件的使用并没有任何的限制。你也可以使用任何标准的 ASP.NET 服务器控件、用户控件、或者自定义服务器控件。该文章讨论了在 Web 部件应用程序中使用非继承自 WebPart
类的控件的相关问题。
创建运行时的 Web 部件控件
至于非派生于 WebPart
类的不同类型的服务器控件,Web 部件的控件集提供了一个机制以允许它们参与 Web 部件应用程序的组成并拥有与派生于 WebPart
类的控件相同的能力。这并不需要开发者做任何额外的特定动作;所必需仅仅是把服务器控件添加到一个 WebPartZoneBase
区域中。一旦 Web 页面被编译,区域中的任何服务器控件以及非继承自 WebPart
类的控件都被自动封装到 GenericWebPart
类的一个实例中,并且成为该实例的子控件。因为 GenericWebPart
类继承自 WebPart
类,所以子服务器控件都能够拥有 WebPart
控件的完整功能。基本上,只要把非继承自 WebPart
类的服务器控件添加到 WebPartZoneBase
区域中,开发者就能够让这些控件成为运行时的 WebPart
控件。
提示:与在 Web 部件应用程序中使用服务器控件类似,你同样也能够在 Web 部件应用程序之外使用 WebPart
控件。如果你把一个继承自 WebPart
类的控件添加到页面的区域之外,那么它将变成一个标准的服务器控件并因此而失去所有的 Web 部件能力。
为区域添加 ASP.NET 服务器控件
当你在为 WebPartZoneBase
区域添加 ASP.NET 服务器控件、用户控件、或者自定义控件的时候,并不需要使用任何必需的特定技术或者页面声明。你可以通过平常为 Web 页面添加控件时相同的方式来为区域添加这些控件:声明(在页面的结构中)、或者编程。另外,你还可以使用 Web 部件的目录特征,该特征允许你把服务器控件添加到目录中,从而用户能够在运行时选择相应的控件,并把它添加到页面中进行使用。关于详细内容,请参考:DeclarativeCatalogPart
控件和 ImportCatalogPart
控件。
如果你需要通过编程为区域添加服务器控件,推荐使用 WebPartManager
控件的 AddWebPart
方法。
当你通过声明的方式为区域添加非 WebPart
服务器控件的时候,如果你使用的是可视化设计工具(如 Microsoft Visual Studio 2005),你将无法在属性面板或者智能提示中查看到 WebPart
的属性和成员。关于详细内容,请参考下列部分对使用 WebPart
控件还是使用其他服务器控件的讨论。
决定使用不同服务器控件选项的时机
开发者也许会想,既然他们能够在 Web 部件应用程序中使用任何种类的服务器控件,那么就有足够的理由来创建派生自 WebPart
类的控件。在多数情况下,首选是使用 ASP.NET 服务器控件、用户控件、或者自定义控件,特别是如果当控件已经存在的情况下。当你使用这些类型的服务器控件、并且你需要获取更多优势(如重用现有代码、以及提升你对控件开发的认识并应用到 Web 部件应用程序中)的时候,你并不会失去任何在运行时的 Web 部件的能力。
此外,你可以通过为 WebPart
类实现特定接口的方式以使得这些不同类型的服务器控件表现得更像是真正的 WebPart
控件。这些需要被了解的接口如下。
-
IWebActionable
接口。如果你实现了这个接口,你将能够为你的控件的动作菜单添加自定义的动作(用户能够在 UI 控件中完成公共动作,如最小化、关闭、或者编辑)。 -
IWebEditable
接口。如果你实现了这个接口,你可以把自定义的EditorPart
控件和你的服务器控件进行关联,以允许用户在运行时编辑控件的特定自定义属性和行为。 -
IWebPart
接口。如果你实现了这个接口,你的控件将会拥有继承自Part
类的真正的WebPart
控件的多数属性,并给予它与WebPart
控件相同的外观和感觉,在设计时也是这样。
创建作为 WebPart
控件的控件时的最主要的好处就是你能够获得超出 Web 部件特定行为之外的完整控制。当控件开发者改变了控件的运行时行为,并且把它分配给用户的时候就会出现这样的一个实例。某个开发者可能覆盖了 WebPart
类的虚拟属性(如 AllowClose
属性),并使它变成一个只读属性,且始终返回 false
值。这就防止了该控件始终不能够被关闭,并且控件的用户也受限于这个行为。
第二个实例就是你能够从对 WebPart
类进行继承并关联到设计时行为的过程中受益。在 WebPart
控件中,所有被暴露的 WebPart
成员在设计时能够通过智能提示(如果他们使用了可视化设计工具,如 Microsoft Visual Studio 2005)而对于开发者可见,所以他们可以在声明模式以及属性面板中对属性进行操作。相反,如果你在运行时为区域声明了非派生于 WebPart
的服务器控件,你就无法在智能提示或者属性面板中查看到 WebPart
类(尽管你仍然可以进行声明)的任何特定成员。那是因为在设计时,一个普通的服务器控件并没有被封装到 GenericWebPart
对象中,所以它不具有任何 WebPart
特征,它只能够在运行时才能具有这些特征。通常实现上述所列的接口并允许服务器控件扮演 WebPart
控件的角色来创建简单的 WebPart
控件才是最直接的方法。创建控件包的开发者能够从继承自 WebPart
类的控件中获益,因为他们能够为他们的控件提供更丰富的设计时特征。
把用户控件当成 WebPart
控件
用户控件是 ASP.NET 开发者的强大选项,因为它们允许开发者在 Web 页面中使用相同的声明语法来快速地建立复杂控件的 UI,同时它们也为跨多个页面之间划分并重用代码而提供了一个便利的方法。与 ASP.NET 服务器控件一样,用户控件也是在 Web 部件应用程序中使用的一个卓越选项。用户控件能够直接被添加到 WebPartZoneBase
区域中,并且它们将会具备运行时 WebPart
控件的全部功能,与上面所描述的一样。它们同样能够与 Web 部件的目录特征一起被使用,或者与控件一样能够被导入,或者封装其他服务器的控件集让用户能够进行选择并添加到页面中(关于更多信息,请参考:WebPartsListUserControlPath
属性)。
重要提示:你应该了解到 ASP.NET 的输出缓存特征在运行时用户控件被当成 WebPart
控件来使用的时候是被禁用的。Web 部件的控件集需要这些控件来组成控件树并提供给每一个被请求的页面。这是特定 Web 部件特征(如个性化,关于详细内容,请参考:Web 部件个性化概览)正常运行所必需的。如果用户控件在请求中被缓存(关于详细内容,请参考:@ OutputCache
指令),那么它就无法被添加到控件树中。因为这个原因,输出缓存与 Web 部件的特征是相矛盾的,并且无法与 Web 部件应用程序中拥有 WebPart
控件功能的用户控件一起工作。