10.2 主题
主题是ASP.NET 4.5基于文本的样式定义,其优点在于设计网站时可以不考虑样式,以后应用样式时也无须更新页或应用程序代码。此外,还可以从外部资源获得自定义主题,以便样式设置应用于应用程序。
10.2.1 主题的构成
主题是一些控件及其属性设置的集合,使用这些属性的设置可以定义页面和控件的外观。主题是由皮肤文件和其他一组文件组成的。通过皮肤文件来定义控件的样式,这样就只需要改变网站主题就可以改变网站的风格了。
主题由外观、级联样式表(CSS)、图像和其他资源组成,它是在网站或Web服务器上的特殊目录中定义的。
1.皮肤文件
皮肤文件又称为“外观文件”,是具有文件扩展名.skin的文件,在皮肤文件里,可以定义控件的外观属性。皮肤文件形式一般具有以下代码:
上面的代码与定义一个LinkButton控件,除了不包含ID、Text等属性外和通常定义LinkButton控件的代码几乎一样。就是这样一行简单代码就定义了LinkButton控件的一个皮肤,可以在网页引用该皮肤去设置LinkButton控件的外观。
2.级联样式表
级联样式表(Cascading Stytle Sheet)简称“样式表”。就是通常所说的CSS文件,它是具有文件扩展名.css的文件,也是用来存放定义页面元素外观属性的代码文件。在页面开发中,采用级联样式表,可以有效地对页面的布局、字体、颜色、背景和其他效果实现更加精确的控制,而且只要对相应的代码做一些简单的修改,就可以改变同一页面的不同部分外观属性,或者页数不同的网页的外观和格式。由于级联样式表具有上面的功能,所以在主题技术中综合了级联样式表的技术。级联样式表一般具有下面代码的形式:
上面的代码中第1行~第6行定义TextBox控件的样式,其中,第2行~第5行分别设置该控件边上下左右边框的颜色和粗细。第7行~第10行定义Button控件的样式,其中,第8行设置控件上显示文字的尺寸,第9行设置控件的颜色。
3.图像和其他资源
图像就是图形文件,其他资源可能是声音文件、脚本文件等。有时候为了控件美观,只是靠颜色、大小和轮廓来定义并不能满足要求,这时候就会考虑把一些图片、声音等加到控件外观属性定义中去。例如,可以在为Button控件的单击加上特殊的音效,为TreeView控件的展开和收起按钮定义不同的图片等。
主题的应用范围可以分为两种:
(1)页面主题应用于单个Web应用程序,它是一个主题文件夹,其中包含控件外观、样式表、图形文件和其他资源,该文件夹是作为网站中的\App_Themes文件夹的子文件夹创建的。每个主题都是\App_Themes文件夹的一个不同的子文件夹。
(2)全局主题可应用于服务器上的所有网站,全局主题与页面主题类似,因为它们都包括属性设置、样式表设置和图形。但是,全局主题存储在对Web服务器具有全局性质的名为Themes的文件夹中。服务器上的任何网站以及任何网站中的任何页面都可以引用全局主题。
在使用主题时,要注意以下一些问题:
● 主题只在每个页面、每个服务器控件或对象中才有效。
● 母版页上不能设置主题,但是主题可以在内容页面上设置。
● 主题上设置的服务器控件的样式会覆盖页面上设置的样式。
● 如果在页面上设置EnableTheming属性为false,则主题设置无效。
● 要在页面中动态设置主题,必须在页面生命周期Page_Preinit事件之前。
10.2.2 主题的创建
在页面应用主题之前,必须创建一个主题,然后才能在本页面或整个应用程序中使用该主题。下面以一个实例来演示创建主题的方法。
【实例10-6】主题的创建
本实例演示如何在一个ASP.NET Web应用程序中创建一个主题和皮肤文件,具体实现步骤如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例10-6”。
02 用鼠标右键单击应用程序名“实例10-1”,在弹出的快捷菜单中选择“添加”|“添加ASP.NET文件夹”|“主题”命令,此时就会在该网站项目下添加一个如图10-13所示的名为App_Themes的文件夹,并在该文件夹中自动添加一个默认名为“主题1”的主题文件夹。
图10-13 生成文件夹
03 用右键单击“主题1”的文件夹,在弹出的快捷菜单中选择“添加”|“添加新项”命令,弹出如图10-14所示的“添加新项”对话框,选择“已安装模板”下的“Visual C#”模板,并在模板文件列表中选中“外观文件”,然后在“名称”文本框输入该文件的名称SkinFile.skin,最后单击“添加”按钮。
图10-14 “添加新项”对话框
04 此时,在“主题1”的文件夹会生成一个如图10-15所示的SkinFile.skin皮肤文件。
图10-15 生成皮肤文件
05 单击生成的SkinFile.skin文件,打开该文件,在里面可以看到的代码如下:
上面代码是一段对外观文件编写的说明性文字,告诉开发人员以何种格式来编写控件的外观属性定义。其中,第4行和第8行提供了两个外观定义的示例,一个是服务器列表控件,另一个是服务器图像控件Image。
06 按照以上的说明格式,在上面的代码中,添加编写一个Button控件的外观属性定义,代码如下:
上面的代码中定义了一个服务器按钮控件Button标签控件的外观,设置其SkinID属性的名称以及背景和文字的显示颜色。
通过以上步骤,一个可以应用于整个网站项目的主题就建立完成了。
10.2.3 主题的使用
在网页中使用某个主题都会在网页定义中加上“Theme=[主题目录]”的属性,代码如下:
为了将主题应用于整个项目,可以根据项目根目录下的Web.config文件里进行配置,示代码如下:
上面的代码中主题的配置是在配置文件的configuration节点下的system.web节点中进行。第3行代码通过使用Pages节点把属性Themes设置为“主题1”,从而将该主题应用于整个项目。
只有遵守上述配置规则,在皮肤文件中定义的显示属性才能够起作用。
在ASP.NET 4.5中属性设置的优先级规则是:如果设置了页的主题属性,则主题和页中的控件设置将进行合并,以构成控件的最终属性设置。如果同时在控件和主题中定义了同样的属性,则主题中的控件属性设置将重写控件上的任何页设置。使用这种属性规则的明显好处是:通过主题可以为页面上的控件定义统一的外观,同时如果修改了主题的定义,页面上的控件属性也会跟着做统一的变化。
ASP.NET 4.5中为Web控件提供的一个联系到皮肤的属性SkinID,用来标识控件使用两种类型的控件外观:默认外观和命名外观。其中,默认外观自动应用于同一类型的所有控件;命名外观是设置了SkinID属性的外观。如果控件没有设置SkinID属性,则使用默认外观。例如如果为TextBox控件创建一个默认外观,则该控件外观适用于使用本主题页面上所有的TextBox控件。
有时需要同时为一种控件定义不同的显示风格,这时可以在皮肤文件中定义SkinID属性来区别不同的显示风格。以下代码中对Label控件定义了三种不同的皮肤:
上述代码中第1行代码是默认定义,不包含SkinID属性,该定义作用于所有不声明SkinID属性的Label控件;第2行和第3行代码声明了SkinID属性,当使用其中一种样式定义时就需要在相应的Label控件里声明相应的SkinID属性。
【实例10-7】主题的使用
本实例演示如何当用户选择不同的主题后,实现页面中控件背景色的不同显示。具体实现步骤如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例10-7”。
02 在网站根目录下创建一个名为Default.aspx的窗体文件。
03 在网站中创建两个主题目录,并在主题目录下各创建一个皮肤文件,命名为One.skin,如图10-16所示。
图10-16 创建主题
04 单击创建网站的根目录下Default.aspx文件,进入到“视图设计器”。从“工具箱”分别拖动两个TextBox控件和一个Button控件到“设计视图”中。切换到“源视图”,编写关键代码:
上面的代码中第1行定义@Page指令,设置关键属性Theme的值为主题目录的名称OneTheme,表明把OneTheme主题应用于该页面。第2、3行各定义一个服务器文本框控件TextBox1并设置SkinID的属性。
05 单击新建的One.skin文件,在其中添加如下代码:
上面的代码中,给两个文本框控件设置背景色、文字的前景色、边框样式和边框的颜色以及关联SkinID属性值。
06 单击网站目录下的Default.aspx.cs文件,编写如下关键代码:
上面的代码中设置在两个文本框控件上显示的文本。
07 按快捷键Ctrl+F5运行程序,如图10-17所示,两个文本框根据主题中的设置显示不同的样式外观。
图10-17 运行效果
10.2.4 用编程的方式控制主题
除了在页面声明和配置文件中指定主题和外观首选项之外,还可以通过编程方式应用主题。可以通过编程方式同时对页面主题进行设置。
当主题被制作完成后,很多场合用户希望能够自行更改主题,这种方式非常地实用,通过编程手段,只需要更改Page页面的Theme属性就能够对页面的主题进行更改。通过编程的方法不仅能够更改页面的主题,同样可以更改控件的主题,达到动态更改控件主题的效果。当需要更改页面主题时,可以更改页面的Theme属性即可实现页面主题更改的效果,Theme属性的更改代码只能编写在PreInit事件中,示例代码如下所示:
上述代码则通过更改Page的Theme属性对页面的主题进行更改,在编程的过程中,同样可以使用更加复杂的编程方法实现主题的更改。在更改页面的代码中,必须首先重写Theme属性,然后通过其中的get访问器返回样式表的主题名称,示例代码如下所示:
对于控件,可以通过更改控件的SkinID属性来对控件的主题进行更改,示例代码如下所示:
上述代码通过修改控件的SkinID属性修改控件的主题,在控件中,SkinID属性是能够将控件与主题进行联系的关键属性。
【实例10-8】动态加载主题
本实例创建三个主题,分别用来定义三个TextBox控件,然后在页面根据下拉列表的选择来动态更换不同的主题,具体步骤如下:
01 Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例10-8”。
02 在网站中创建三个主题目录,分别为BlueTheme、OrangeThemes和RedThemes,并在目录下创建三个皮肤文件Blue.skin、Orange.skin和Red.skin。
03 在网站目录下创建一个名为Default.aspx的窗体文件。
04 双击Default.aspx文件,进入到“视图编辑”界面,进入“源视图”,添加关键代码如下:
上面的代码中第1行定义一个服务器文本框控件TextBox1。第2行~第6行定义一个服务器下拉列表框控件DropDownList1并设置自动回传属性,其中,第3行~第5行添加三个列表选项。
05 用鼠标分别单击单击Blue.skin、Orange.skin和Red.skin文件,在其中添加如下代码:
上面的代码中三个文本框不同的前景色和背景色。
06 单击网站目录下的Default.aspx.cs文件,编写如下关键代码:
上面的代码中第1行定义处理页面PreInit事件的方法,第2行设置Page对象的属性
Theme,根据下列列表框中选定的项加载相应的主题。
07 按快捷键Ctrl+F5运行程序,运行结果如图10-18所示。
图10-18 运行结果
10.2.5 主题的禁用
默认情况下,主题将重写页和控件外观的本地设置,有时候,当控件或页已经有预定义的外观,且又不希望主题重写它时,就可以利用禁用方法来忽略主题的作用。
禁用页的主题通过设置@Page指令的EnableTheming属性为false来实现,例如下面的代码使用EnableTheming属性设置主题的禁用:
如果要禁用控件的主题,则可以通过将控件的EnableTheming属性设置为false来实现,例如下面的代码实现在控件中使用EnableTheming属性设置主题的禁用: