初学者。博客仅做个人的理解整理,不到位的地方欢迎大佬们指出,感谢。
0.什么是资源
一个样式、图片、画刷、对象、普通变量都可以当作资源。
0.1如何定义一个资源
每个控件都有一个resource属性,可以在本身的resource里面定义资源。举个例子在window窗体定义一个样式资源。
<Window.Resources> <Style TargetType="Button" x:Key="btn"> <Setter Property="Content" Value="没触发"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Content" Value="触发了" /> </Trigger> </Style.Triggers> </Style> </Window.Resources>
0.2资源的作用域
在<Window.Resources>里面定义的资源,他的作用域就是当前窗体的所有子控件,那么当前窗体内部的所有控件都可以使用这个样式。
如果写在控件内部,那么这个控件和这个控件的子控件都可以使用。
一个控件在引用资源时是先丛自身资源里找,找不到的话在向父控件里找,一直找到window.Resource,然后找<Application.Resources>
<Grid> <Border Margin="20" Background="Green"> <Border Margin="20" > <Border.Resources> <Style TargetType="Border"> <Setter Property="Background" Value="Red"/> </Style> </Border.Resources> <Border Margin="20" Background="Blue" > </Border> </Border> </Border> </Grid>
1.什么是资源字典,为什么需要资源字典
为了资源的可重用性,把资源定义在资源字典里。
2.如何新建一个资源字典
项目右键新建一个资源字典,后缀名是 .xaml
空白资源字典是这个样子的
把定义的style资源放进去
3.如何引用一个资源字典
在MainWindow.xaml里面写这句,就能引用
<Window.Resources> <ResourceDictionary Source="Dictionary1.xaml"/> </Window.Resources>
或者写全路径
<ResourceDictionary Source="pack://application:,,,/资源字典;component/Dictionary1.xaml"/>
布局代码
<Grid> <StackPanel> <Button/> <Button/> <Button/> <Button/> <Button/> </StackPanel> </Grid>
效果图:
4.资源字典的合并
再定义一个样式,把button的background设置成蓝色,现在总共有2个资源字典
在引用时报错
这时候要合并资源字典
<Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/资源字典;component/Dictionary1.xaml"/> <ResourceDictionary Source="pack://application:,,,/资源字典;component/Dictionary2.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources>
效果图:
有几点需要总结一下:
1. 2个资源字典里面的style都对button的背景色修改了,结果是后引用的生效。
2.style不管是写在哪里,只要不写key,则作用域内所有目标控件都自动引用,写key默认不引用,需要手动引用
3. 不同资源字典内部的资源名可以相同,后引用的生效
5.静态资源和动态资源
静态资源一旦编译就不能再修改,动态资源可以再程序运行时监听到资源的修改,下面做个实例
静态资源引用方式
<Button Style="{StaticResource s1}"/>
动态资源引用方式
<Button Style="{DynamicResource s1}"/>
6.如何在后台代码修改引用的资源字典
2个资源字典,每个资源字典里面都写了一个button的style,点击按钮,切换style
首先给ResourceDictionary添加一个名字:
后台代码:
private void b5_Click(object sender, RoutedEventArgs e) { this.rd3.Source = new System.Uri("pack://application:,,,/资源字典;component/Dictionary1.xaml"); }
有个疑问:Resource Dictionaty的名字必须写在1处,写在2处,再后台代码访问不到这个名字
到时候所有的资源字典都要合并到ResourceDictionary.MergedDictionaries里面。我在Dictionary1和Dictionary2里面写的时button的style,再Dictionary3里面写的是border的style,如果再后台用Dictionary2替换Dictionary1。那么border会受影响吗?
经过测试发现不会,也就是说,虽然把不同类型的资源字典合并到一个ResourceDictionary里面,但是再后台修改时,只会影响新加的资源字典的targetname的目标类型,其他类型的控件不会受到影响。
总结说:用新资源字典去替换之前的资源字典,this.rd3.Source = new System.Uri("pack://application:,,,/资源字典;component/Dictionary1.xaml"); 这个新资源字典里面是哪个控件就修改哪个控件。其他控件不受影响。
如果资源字典里面的style不写key,应该是默认是动态引用的方式,测试结果是这样的,
如果资源字典里面的style写key了,那想要再后台代码修改,必须使用Style="{DynamicResource style的名字}" ,不然改不了
<StackPanel> <Button Style="{DynamicResource s1}"/> <Button Style="{StaticResource s1}"/> <Button Style="{StaticResource s1}"/> <Button Style="{StaticResource s1}"/> <Button Name="b5" Style="{StaticResource s1}" Click="b5_Click"/> <Border Height="30" Width="500" Style="{StaticResource myborder}"/> </StackPanel>
效果图:(资源字典里的style写了key,第一个按钮使用动态引用,其余的使用静态引用,默认是蓝色,修改后是红色)