前言
在Web前端开发中有这么几种元素
- HTML+模板
- CSS
- JS
WPF和HTML页面类似用XML进行页面编程,那么上述的模板
、CSS
和JS
放在哪呢?
答案就是Window.Resources
中
什么叫WPF的资源(Resource)?
资源是保存在可执行文件中的一种不可执行数据。在WPF的资源中,几乎可以包含图像、字符串等所有的任意CLR对象,只要对象有一个默认的构造函数和独立的属性。
也就是说,应用程序中非程序代码的内容,比如点阵图、颜色、字型、动画/影片档以及字符串常量值,可将它们从程序中独立出来,单独包装成”资源(Resource)”。
静态资源(Static Resource),动态资源(Dynamic Resources)。
这两者的区别是:
静态资源在第一次编译后即确定其对象或值,之后不能对其进行修改。
动态资源则是在运行时决定,当运行过程中真正需要时,才到资源目标中查找其值。
因此,我们可以动态地修改它。由于动态资源的运行时才能确定其值,因此效率比静态资源要低。
资源的范围(层级)
WPF提供一个封装和存取资源(resource)的机制,我们可将资源建立在应用程序的不同范围上。WPF中,资源定义的位置决定了该资源的可用范围。资源可以定义在如下范围中:
- 物件级:此时,资源只能套用在这个Object物件,或套用至该物件的子物件。
- 文件级:如果将资源定义在Window或Page层级的XAML档中,那么可以套用到这个文件中的所有物件。
- 应用程序级:如果我们将资源定义在App.xaml 中,那么,就可以将资源套用到应用程序内的任何地方。
- 字典级:当我们把资源封装成一个资源字典, 定义到一个ResourceDictionary的XAML文件时,就可以在另一个应用程序中重复使用。
每一个框架级元素(FrameworkElement 或者FrameworkContentElement)都有一个资源属性。每一个在资源字典中的资源都有一个唯一不重复的键值(key),在标签中使用x:Key
属性来标识它。一般地,键值是一个字符串,但你也可以用合适的扩展标签来设置为其他对象类型。非字符键值资源使用于特定的WPF区域,尤其是风格、组件资源,以及样式数据等。
StaticResource和DynamicResource区别
StaticResource和DynamicResource都是WPF中用来引用资源的方式,下面是它们的区别:
- StaticResource:在应用程序启动时解析,即在XAML文件的解析期间被确定。一旦确定,它就会成为那个控件的属性值,而不会再改变。如果资源被修改了,这些修改不会反映到使用StaticResource的控件上。这种方式启动速度快,但是没有动态性。
- DynamicResource:在运行时解析,即在XAML文件的解析期间不被确定。如果资源发生更改,则这些更改将自动更新到使用DynamicResource的控件上。这种方式可以在运行期间动态更新资源,但会在应用程序启动时相对较慢。
在使用ItemsControl的ItemTemplate时,建议使用StaticResource,因为ItemTemplate一般是在控件的生命周期内只需要创建一次,且不需要随着用户交互而动态改变。而DynamicResource则适用于需要动态更改的资源,如界面主题等。
StaticResource的适用场合
StaticResource用于在XAML中创建的一个静态资源,只会在应用程序启动时被创建,占用一定的内存空间,在应用程序整个运行期间不会被释放,所以适用于以下场合:
常用的样式和控件,如按钮、标签等,因为它们在应用程序中会被多次使用,使用StaticResource可以提高性能和减少内存消耗。
程序中不会改变的资源,如图标、字体等,使用StaticResource可以加快应用程序启动速度。
在同一页面中多次使用的资源,如背景颜色、字体等,使用StaticResource可以避免重复定义。
总之,StaticResource适用于那些没必要动态修改的资源,使用起来更加简单高效。
DynamicResource的适用场合
在WPF中,DynamicResource 适用于那些资源可能在运行时被更改或者需要动态更新的情况,而 StaticResource 则用于那些在加载时已经确定好的资源。
因此,在以下情况下使用 DynamicResource 更为合适:
- 在运行时更改应用程序主题或控件样式时。
- 当应用程序需要动态更改资源时。
- 当你想要动态更改控件某些属性时,例如控件的前景色、背景色等。
需要注意的是,使用 DynamicResource 会导致一个稍微较慢的应用程序启动和加载时间,因为这些资源可能需要在运行时计算而不是在编译时确定。
因此,
只有在确实需要它们动态更新的情况下才使用
DynamicResource
,否则应该优先考虑StaticResource
。当然,在实际应用过程中,也可以采用两者混合的方式,根据具体情况决定。
资源的查询方式
Static Resource的查询
- 查找使用该资源的元素的Resource字典;
- 顺着逻辑树向上查找父元素的资源字典,直到根节点;
- 查找Application资源;
- 不支持向前引用,即:不能引用在引用点之后才定义的资源。
Dynamic Resource的查询
- 查找使用该资源的元素的Resource字典;
如果元素定义了一个Style 属性,将查找Style中的资源字典;如果元素定义了一个Template属性,将查找FrameworkTemplate中的资源字典。 - 顺逻辑树向上查找父元素的资源字典,直到根节点;
- 查找Application资源;
- 查找当前激活状态下的Theme资源字典;
- 查找系统资源。
模板
模板的使用有先后顺序,后面的模板才能使用前面的模板。
DataTemplate
设置列表的模板
1 | <Window.Resources> |
使用方式
1 | <ListBox |
ControlTemplate
1 | <Window.Resources> |
CSS
Style的使用
1 | <Window.Resources> |
使用方式
1 | <ListBox |
Style的继承
1 | <Window.Resources> |
JS
这个就是引用C#写的类
IValueConverter
下面的示例主要是根据绑定的值控制组件显示隐藏
1 | <Window.Resources> |
对应的类
1 | using System; |
使用
1 | <views:ZJClippingBorder CornerRadius="4" Visibility="{Binding IsStart, Converter={StaticResource anyTypeConverter}, ConverterParameter='false:Visible|true:Collapsed'}"> |