WPF资源字典

初学者。博客仅做个人的理解整理,不到位的地方欢迎大佬们指出,感谢。

 

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,第一个按钮使用动态引用,其余的使用静态引用,默认是蓝色,修改后是红色)

 

 

posted @ 2021-12-24 19:40  薛定谔的小灯泡  阅读(852)  评论(0编辑  收藏  举报