WPF入门到跪下 第三章 基础知识-对象资源

C#中所有的类都可以在资源中定义实例

C#常用类型的资源定义

注意,.Net环境下,运行库程序集为System.Runtime,Framework环境下则为mscorlib

一、资源的定义

值类型资源的定义

<Window ......
        xmlns:sys="clr-namespace:System;assembly=System.Runtime"//如果是Framework环境下则为clr-namespace:System;assembly=mscorlib
        ......
>
    <Window.Resources>
        <sys:Double x:Key="value">200</sys:Double>
    </Window.Resources>
    ......
</Window>

数组资源的定义

<Window ......
        xmlns:sys="clr-namespace:System;assembly=System.Runtime"
				......
>
    <Window.Resources>
        <!--List<int> datas-->
        <x:Array x:Key="datas" Type="sys:Int32">
            <sys:Int32>1</sys:Int32>
            <sys:Int32>2</sys:Int32>
            <sys:Int32>3</sys:Int32>
            <sys:Int32>4</sys:Int32>
            <sys:Int32>5</sys:Int32>
        </x:Array>
    </Window.Resources>
    ......
</Window>

二、资源的引用

静态引用

语法:{StaticResource ResourceKey=keyName}

  • ResourceKey可以省略,即可以写成{StaticResource keyName}
<Grid>
    <Button Content="button1" Width="{StaticResource ResourceKey=value}" Height="{StaticResource ResourceKey=value}"/>
</Grid>

动态引用

语法:{DynamicResource ResourceKey=keyName}

<Grid>
    <Button Content="button1" Width="{DynamicResource ResourceKey=value}" Height="{DynamicResource ResourceKey=value}"/>
</Grid>

静态VS动态

针对同一个资源,可以使用静态或者动态引入,两者的区别在于,静态引入后,如果运行过程中对资源进行改变,xaml中的对应值是不会有改变的。而动态引入的话,会对该资源进行监听,如果运行过程中对资源进行了改变,xaml中的对应值会发生变化。

动态引用可以运用在文字、主题等的动态替换上。

此外,有时候需要在运行时才能加载到资源的,也要使用动态引用才更为合理。

自定义类型的资源定义

要将自定义类型对象作为WPF资源,具体有如下3个步骤:

  • 创建自定义类型
namespace WPFResource
{
    public class MyResource
    {
        public string name { get; set; } = "Schuyler";
    }
}
  • 引入该类型所在的命名空间。
  • Window.Resources元素中进行引用。
<Window ......
        xmlns:local="clr-namespace:WPFResource"
				......
>
    <Window.Resources>
        <local:MyResource x:Key="myResource" name="Schuyler"/>
    </Window.Resources>
		......
</Window>

对象数据提供程序-ObjectDataProvider(重要)

ObjectDataProvider是WPF中的一个数据提供程序,可以帮助我们在WPF中创建数据对象。

以上文中的自定义类型为例,可以通过ObjectDataProvider在视图中创建资源

  • 示例

    <Window ......
            xmlns:local="clr-namespace:WPFResource"
    				......
    >
        <Window.Resources>
            <ObjectDataProvider ObjectType="local:MyResource" x:Key="myResource"/>
        </Window.Resources>
    		......
    </Window>
    

如果想要创建带参构造函数的对象,可以使用ObjectDataProvider.ConstructorParameters设置构造函数的参数。

  • 示例

    public class MyResource
    {
        public string Name { get; set; }
        
        public MyResource(string name)
        {
    	      Name = name;
        }
    }
    
    <Window ......
            xmlns:local="clr-namespace:WPFResource"
            xmlns:sys="clr-namespace:System;assembly=System.Runtime"
    				......
    >
        <Window.Resources>
            <ObjectDataProvider ObjectType="local:MyResource" x:Key="myResource">
    		        <ObjectDataProvider.ConstructorParameters>
    				        <sys:String>Schuyler</sys:String>
    		        </ObjectDataProvider.ConstructorParameters>
            </ObjectDataProvider>
        </Window.Resources>
    		......
    </Window>
    

资源作用域

在上文中可以看到,资源都是在Resources属性下进行定义的,而ResourcesFrameworkElement类中的属性成员,几乎所有的WPF控件都为该类的子类,也就是说,基本上所有容器控件都可以使用Resources属性来进行资源的定义。这也就产生了不同的作用域,上文中是使用了Windows控件的Resources属性进行资源定义的,也就是该窗体中的所有控件都能访问到所定义的资源。

此外,WPF在使用资源时,会一层一层的向上寻找,当前控件中没有对应资源就找父类中的资源,如果还是没有就找父类的父类中的资源,一直到当前XAML文件的最顶级元素中的资源,如果在没有,就会跳转到App.xaml文件中的资源寻找。

  • 总结下来的资源寻找顺序为:自身资源->父级资源->……->窗口资源->应用程序资源->框架系统资源。

这里有个需要注意的地方,WPF在进行渲染时,也是一层层从顶级元素向内加载的,因此如果希望在某个控件的属性中使用该控件定义的资源,那么该属性就必须放置在定义资源之后。

  • 在定义资源之前引用资源,此时属性加载,而该控件的资源定义还未加载,因此直接引用了父类的资源。
<Window x:Class="WPFResource.MainWindow"
        ......
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:WPFResource"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <sys:Double x:Key="value">500</sys:Double>
    </Window.Resources>
    <Border Height="{StaticResource value}">
        <Border.Resources>
            <sys:Double x:Key="value">200</sys:Double>
        </Border.Resources>
    </Border>
</Window>
  • 在定义资源之后引用资源,此时成功加载本控件定义的资源。
<Window.Resources>
    <sys:Double x:Key="value">300</sys:Double>
</Window.Resources>
<Border>
    <Border.Resources>
        <sys:Double x:Key="value">200</sys:Double>
    </Border.Resources>
    <Border.Height>
        <StaticResource ResourceKey="value"/>
    </Border.Height>
</Border>

如果希望定义的资源,在整个应用中的所有xaml文件都能够访问到,可以将其定义在App.xaml的Resource中。

<Application ......
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
						 ......
>
    <Application.Resources>
        <sys:Double x:Key="value">200</sys:Double>
    </Application.Resources>
</Application>
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SchuylerEX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值