一、 自动格式化
,
"p_w_picpath/gif")>
现在,让我们开始讨论本文中最有趣的内容。你是否曾把一个GridView拖动到一个表单上并且注意到在属性浏览器有一个标有“Auto Format…”的链接?当你点击它时,你会得到一个预定义格式的选择:例如Corporate,Elegant,Classic,等。事实上,随着 ASP.NET 2.0发行的所有安全控件套件(Security Control Suite)都提供了这个特征。读完本节后,你一定会为在你的控件中提供这种功能的容易程度而感到吃惊。
首先,我要确定我想在控件中提供什么格式。我将通过创建三种格式来简化操作。其中的两个分别称为“Monochrome”和“Colorful”。第三个(实际上是第一个)称为“No Format”;当把它拖动到一个表单时,它能够把控件恢复到其原始状态。
我创建的每一种格式都需要它自己的继承自System.Web.UI.Design命名空间的DesignerAutoFormat类。因此, 我先从一个称为ColorfulFormat的继承自DesignerAutoFormat的类开始。首先,我需要为这个类提供一个缺省的构造器;并且我 将在其中调用基类的构造器,发送给它一个参数—格式名称(将出现在列表中)。
以下是引用片段: Public Sub New() MyBase.New("Colorful") End Sub |
接下来,我必须重载Apply方法。这个方法接收一个Control类型的参数。我的控件设计器类将调用这个方法,并且把我的控件实例发送到这个参数中。然后,我要把该参数转化成我的控件类型;这样以来,我就有一个可以使用的强类型引用了。
以下是引用片段: Public Overrides Sub Apply( _ ByVal control As System.Web.UI.Control) Dim ourControl As EmailContact2 = CType(control, EmailContact2) If ourControl IsNot Nothing Then ... End If End Sub |
现在,我要设置我需要的任何属性—这通常包括一些风格属性,但是它事实上能够包括我需要的一切。因此,在“IsNot Nothing”检查中,针对这个特定的格式,我只需简单地设置我想实现的任何风格属性。列表2展示了完整的列表。
以下是引用片段: ourControl.BackColor = Drawing.Color.Aquamarine ourControl.BorderStyle = BorderStyle.Double ourControl.BorderWidth = Unit.Pixel(2) ourControl.BorderColor = Drawing.Color.DarkRed ourControl.HeadingStyle.Font.Name = "arial" ourControl.HeadingStyle.Font.Bold = True ourControl.HeadingStyle.Font.Size = FontUnit.Large |
接下来,我将创建一个称为MonochromeFormat的类并且执行相同的步骤—仅在这次,我把风格属性设置为black和white以相应于一种“monochrome”格式。源码文件中的列表3展示了这个类的完整代码。
最后,我必须创建NoFormat类。这个类遵循与前两个相同的设计;但是,我不是把风格属性值设置成各种颜色及字体,而是在所有的风格属性上调用Reset方法。这可以把所有的风格值设置为它们的缺省状态。
顺便说一下,既然我的EmailContact控件派生自CompositeControl类,而它又派生自WebControl类;所以,我 还可以在我的控件的类级上取得风格属性。这意味着:我可以拥有BackColor,ForeColor等属性,而且可以直接从我的控件中存取它们而不必通 过一个属性来实现。然而,为了复位这些风格值,我不是直接从我的控件类取得一个Reset方法,而是由WebControl类为我提供了一个 ControlStyle属性,它用作相应于所有的容器风格值的入口点。注意:在复位控件的外观时,我还把Height属性设置为一个具有400个像素的 缺省值。下面是完整的类:
以下是引用片段: Public Class NoFormat Inherits DesignerAutoFormat Public Sub New() MyBase.New("No Format") End Sub Public Overrides Sub Apply(ByVal control _ As System.Web.UI.Control) Dim ourControl As EmailContact2 = CType(control, _ EmailContact2) If ourControl IsNot Nothing Then ourControl.ControlStyle.Reset() ourControl.HeadingStyle.Reset() ourControl.CaptionStyle.Reset() ourControl.FieldStyle.Reset() ourControl.ReadonlyFieldStyle.Reset() ourControl.ButtonStyle.Reset() ourControl.Height = Unit.Pixel(400) End If End Sub End Class |
现在,既然我已经创建了我想实现的所有格式类,那么,接下来,我需要对它们做一些实际的操作。为此,我将再转回到控件设计器类—实现一些重载。 我需要重载的属性称为AutoFormats,它返回一个System.Web.UI.Design命名空间中的 DesignerAutoFormatCollection类型的对象。
就象在灵敏标签和模板编辑部分一样,我将实例化的对象(为了通过属性返回之)是在类级上声明的,因为ASP.NET基础结构会负责对它进行缓冲处理。
以下是引用片段: Private o_AutoFormats As _ DesignerAutoFormatCollection |
然后,在属性重载实现中,我可以测试对象变量是否是一个null值。现在,我们只需简单地使用我以前创建的每一个格式类的实例来填充o_AutoFormats集合对象。
以下是引用片段: Public Overrides ReadOnly Property AutoFormats() _ As DesignerAutoFormatCollection Get If o_AutoFormats Is Nothing Then o_AutoFormats = New DesignerAutoFormatCollection With o_AutoFormats .Add(New NoFormat) .Add(New MonochromeFormat) .Add(New ColorfulFormat) End With End If Return o_AutoFormats End Get End Property |
如果我重新编译并再次测试该控件,我将看到一个称为“Auto Format…”的链接被添加到灵敏标签的顶部。如果以前不存在灵敏标签,那么Visual Studio将自动地使用“Auto Format…”链接在其中创建一个。你将还注意到一个“Auto Format…”链接出现在属性浏览器的底部。
如果我点击任何一个链接,我将看到如图4所示的内容。选择列表中的任何一种格式从而在预览窗口中改变它;然后点击OK把此设置提交给Web表单设计界面下的控件。
图4.自动格式化屏幕
现在,既然你已经了解了如何进行格式化,那么接下来,你应该学习何时以及为什么进行格式化。
我仿佛听到CSS爱好者正在对本文大声叫喊。其实,我本人就是一个“层叠式样表(CSS)”迷,并在我所有的站点中使用它们。自动格式化特征在 有些情况下(例如控件组)是非常有用的。例如,我们不妨考虑微软的安全控件套件(Security Control Suite)。从中,你会看到七种Web控件可用于一个站点中以为页面添加认证功能。其中,每一种控件都提供了自动格式化功能,并且每一个控件都显示一样 的列表用于从中选择一个格式—这是相当不错的功能。
试想一下我们今天已经实现的一些流行的可视化效果:例如Outlook工具栏中的许多风格,各种TreeView控件,菜单和工具栏,等。你完全可以把这其中的许多特征集成到几乎任何站点的设计风格中。在这种情况下,自动格式化是一种相当有用的工具。
现在请记住,在每一个格式类中,我把风格值改变为我的一些风格属性。如果你在Web表单中应用这些格式中的任一个,那么,你将会看到这些风格值 确实在属性浏览器中改变了。如果我想(尽管我不会选择)这样做的话,那么我可以修改style属性的CssClass值,并且把一个风格表类指派给它们。 这当然可以顺利地工作,但是之后,我需要同我的控件一起发布该CSS文件,并且还要确保页面链接到它。
如果我能够在我的控件中使用这些资源文件而不必随同控件的DLL文件一起发行它们,不是相当酷吗?好,下面我们来讨论本文的最后一个话题—Web资源。
一、 Web资源
Web资源是被编译到你的控件DLL中的一些嵌入式文件。Windows表单控件开发者很久以来就拥有这种能力,只是到现在它才被应用于Web 领域。让我们想象开发一个依赖于某些图像才能正确生成的控件的情形。只是简单地发布该控件相应的DLL文件而不必考虑单独发布外部图像文件,这是特别有用 的。分析一下微软提供的新的Tree Web控件,那么你就会发现这一特征。在此,图像文件是讨论使用Web资源的最佳候选,尽管我们还能够把它们使用于JScript文件中。
为了说明这一问题,我想把一个邮箱图像添加到我的EmailContact控件标题的左边。你可能已经注意到,在图4中“CONTACT US”标题文字的左边已经存在一个空图像。为此,我是通过简单地创建一个Image子控件并且把它添加到控件层次中的适当位置来实现的。事实上,我还创建 了一个称为ShowMailIcon的属性以允许页面开发者隐藏/显示图像。
使用常规方法就能创建一个HeadingImageUrl字符串属性,并且在图像控件的ImageUrl属性中设置它的值。这将允许页面开发者 把这个图像设置为他所希望的任何内容。我同意这一方法,而我在这个控件中就使用了这种方法。然而,我更深入了一步。如果HeadingImageUrl属 性不是空的,那么我使用它填充图像控件的ImageUrl属性(如前所述);但是如果该属性是空的,那么我要实现一些更酷的内容。
在我的Web控件工程中,我有一个称为mailbox.gif的邮箱图像。我将把图像的BuildAction属性设置为EmbeddedResource(注意,我可以通过属性浏览器来实现这一点)。
接下来,我需要存取我的工程的AssemblyInfo.vb文件。在ASP.NET 1.1中,这个文件位于我的工程的根文件夹下,但是在ASP.NET 2.0中,它位于我的工程文件夹下。不仅如此,我还必须点击属性浏览器顶部的“Show All Files”按钮存取这个文件。在AssemblyInfo.vb文件的底部,我需要添加下列语句:
这一句把该嵌入式文件标识为一个可用的Web资源,以便于后面的提取操作。
为了提取该文件,我使用了Page.ClientScript对象的GetWebResourceUrl方法。如前所述,我想使页面开发者能够使用我自己的属性重载图像;因此我以如下方式进行提取:
以下是引用片段: If Me.HeadingImageUrl <> "" Then imgMail.ImageUrl = Me.HeadingImageUrl Else imgMail.ImageUrl = Page.ClientScript.GetWebResourceUrl( _ Me.GetType(), "mailbox.gif") End If |
这正是我所喜爱的新的Web控件特征,因为我往往不时地在一些地方使用小图像来修饰我的控件。现在,我能够嵌入它们,并且只需要我的控件的DLL文件。
测试该控件将显示如图5所示的结果。
图5.带有嵌入式图像的最终完成后的控件
该Web表单使用一个HTTP处理器来检索图像并且把它生成到浏览器。显然,这种使用可能性远远不止此。
二、 总结
我希望你喜欢本系列文章所介绍的内容。其实,ASP.NET 2.0在Web开发方面加入了许多酷的内容,例如引入了母板页面,主题,数据源,以及其它优秀特征。事实上,你也可以把回调(一种新的页面特征)嵌入到控 件中,从而为它们加入AJAX功能以实现更好的响应时间并产生一种更为丰富的客户端体验。遗憾的是,有关这一方面的内容已经非本文所及。在本文中所介绍的 新的控件开发特征当前尚不多见;当然,这也是我写本文的原因。如你所见,这其中的大多数内容都与设计时刻体验相关;但是,我一直认为,提高控件的直观性与 使之有用且能够实现既定功能一样重要。如果不容易使用,那么你甚至无法全面地使用该控件所提供的功能。