8.2 主题
主题和外观是ASP.NET 2.0中的新增功能,在ASP.NET 4.0中的“主题和外观”功能有了明显改进,将样式和布局信息分解为单独的文件组,称为“主题”。主题可应用于任何站点,其实就是样式表的另外表现形式,影响站点中页和控件的外观。这样,通过更改主题可轻松维护对站点的样式更改,无需对站点各页进行编辑,还可与其他开发人员共享主题。
ASP.NET提供了一些可在应用程序中对页和控件的外观或样式进行自定义的功能。控件支持Style对象模型,用于设置字体、边框、背景色和前景色、宽度、高度等样式属性。控件还完全支持可将样式设置与控件属性分离的级联样式表(CSS);可以将样式信息定义为控件属性或CSS,也可以在名为Theme的单独文件组中定义此信息,以便应用于应用程序的全部或部分页,各控件样式在主题中被指定为Skin。
“主题”提供了一种简易方式,可以独立于应用程序的页,为站点中的控件和页定义样式设置。多个主题的优点在于设计站点时可以不考虑样式,以后应用样式时也无需更新页或应用程序代码。此外,还可以从外部源获得自定义主题,以便将样式设置应用于应用程序。一个主题的优点在于,样式设置存储在一个位置,可以独立于应用该主题的应用程序来维护这些设置。
8.2.1 创建主题
在ASP.NET程序当中,可以添加多个任意主题,但首先要添加一个主题的系统文件夹App_Themes,如果没有这个文件夹,在添加主题时系统会自动添加此项,该文件夹中存储主题文件。添加主题的过程,首先在解决方案下的应用程序节点上,单击右键,在弹出的右键菜单中,选择“添加”→“添加ASP.NET文件夹”→“主题”命令,如图8-4所示。
图8-4 添加主题
就会在程序的根目录下生成一个App_Themes的文件夹,在这个文件夹下添加一个主题1的文件夹,用来存储和主题1相关的文件,如样式表或图片等。下面将在主题中添加一个皮肤文件,也是主题中最主要的一个文件。选中“主题”命令,单击右键,在弹出菜单中选择“添加→新建项”命令,在新建项菜单中,选择外观文件,输入文件名称,将在主题下默认添加一个外观文件(. skin)。外观文件默认内容如下。
在外观文件中,默认提供了一些实例。在文件下部添加一个文本框的主题文件,主题文件类似于控件,但没有ID和name属性,将编辑好样式的控件去掉ID属性就可以作为主题文件中的样式使用,代码如下。
这里只是设置了文本框的两个颜色,用于区分普通的文本框。在使用主题时,先选择页面的顶部设置Theme属性为刚刚建立的主题名称,这样在运行时就能够看到应用主题的效果,效果如图8-5所示。
图8-5 主题效果
8.2.2 创建命名皮肤
在上面主题创建中,创建了主题也创建了皮肤文件,问题是在使用皮肤时,所有页面都使用了主题文件,那么,所有的文本框都是用了相同的皮肤,这样就失去了对样式灵活控制,所以在创建皮肤时会为皮肤产生一个ID,这样在使用时,就不会因为使用了相同的皮肤文件而导致所有的样式全部统一,既增加了样式的灵活性,又使得程序简单明了。在没有使用皮肤ID的控件中系统将默认显示。下面通过代码看下具体的设置,代码如下。
皮肤代码如下。
应用皮肤控件代码如下。
最后执行效果如图8-6所示。
图8-6 应用了不同皮肤的控件效果
在应用了不同的皮肤ID后,控件呈现的样式将分别显示。
8.2.3 处理主题冲突
在应用了主题的页面上,控件需要指定皮肤的ID,在没有指定皮肤ID的控件时,控件默认是使用皮肤的,在控件指定了皮肤ID后,如果不想使用当前皮肤,还有另外一个属性设置,可以使皮肤的设置失去效果,就是EnableTheming="false"属性,设置了此属性后,皮肤的样式将不再发生作用,控件将还原到没有设置皮肤时的状态。
在应用了主题的页面中,还可以使用另外一种可以被覆盖的主题属性。在使用这种属性时,主题可以被控件设置的样式属性所覆盖,这样,就能灵活地使用控件的属性,具体代码如下。
StylesheetTheme="主题1" %>
在页面的顶部,使用了StylesheetTheme="主题1"属性,就能使控件在窗体上设置的属性覆盖皮肤的属性。设置了皮肤属性的控件的效果如图8-7所示。
图8-7 覆盖皮肤属性的设置
在上面的效果中,为文本框1设置了背景为白色的属性,这样的设置同皮肤的设置是冲突的,但最后的结果是文本框的属性覆盖了皮肤的属性。也就是说在样式设置中有一个唯一的原则。最后设置的属性将覆盖前面所有的属性,前面设置的效果代码如下。
上面代码中就是最后的背景颜色覆盖了前面所有的属性设置。
8.2.4 为整个网站应用主题
在开发的Web应用程序中,每个应用程序或网站都有自己不同的风格,这样,每个网站都需要有自己的一个或几个样式的集合,有时会在不同的风格间直接切换,从而需要有一个能够可以快速切换的风格,这样的网站或应用程序就需要一个或几个主题。
前面设置主题的方式是在每个页面都引入一个主题,这样,对于页面少的程序还可以,但是页面很多,修改和维护起来非常复杂,而且容易出现遗漏。编译器为了解决这一问题,在配置文件中为程序提供了一个配置选项,能够一次设置完成所有的主题,配置项如下。
在设置中使用theme属性,表示强制优先使用主题设置的样式,如果不是以主题的样式为优先使用,可以使用styleSheetTheme这个属性,降低主题中属性的优先级,设置后的效果如图8-8所示。
图8-8 在配置文件中应用样式的效果
配置完程序的主题后,页面上面的主题就可以不再使用了。
8.2.5 添加CSS样式
主题相当于一个特殊的样式集合,在这个集合中可以添加一些样式表等文件来管理样式,便于后期的维护。首先在主题下添加一个样式表文件,命名为inputstyle.css,打开这个文件,设置HTML中input控件的属性,样式表中没有ASP.NET服务器控件,所有样式全部采用IIS解释后输出到界面上的控件为准,所以,设置的是input的控件属性,代码如下。
在使用这个样式表文件中,也和主题中设置的样式存在冲突,如果要使这个样式表中的样式生效,要么使用styleSheetTheme这个属性配置样式表,要么去掉皮肤文件中的样式,才能生效,效果如图8-9所示。
图8-9 使用了样式表的效果
为了能够看得更清楚,这里使用华文彩云字体。
8.2.6 动态应用主题
在程序开发中,几乎所有前台样式和代码都能够通过后台的方式来设置,也就是说,可以通过后台编程方式来控制程序所使用的主题和皮肤,使得应用程序更灵活,尤其是在配置用户自定义信息时。如果没有登录的用户希望有自己的一套自定义主题,需要通过编程方式来为每个不同的用户显示不同的主题。在演示动态引用主题之前,首先添加两个主题,代码如下。
主题1:
主题2:
添加好主题文件后,添加下面代码文件。
上面的代码中添加了两个按钮,分别设置两个不同的主题。单击按钮1应用主题1,单击按钮2应用主题2,效果如图8-10、图8-11所示。
图8-10 主题1效果
图8-11 主题2效果
在使用编程方式设置主题时,不能在窗体加载之后的事件中设置,必须在窗体加载之前的事件中设置主题才有效。