WPF 之资源(九)

一、二进制资源

​ 程序中的各种数据就是算法的原料和粮草。程序中的数据可以放在数据库里、变量里、程序主体之外的文件里。但保存在程序主体之外的文件里,由于外部文件和程序主体分离,容易造成文件丢失或损坏,为了解决此问题,编译器允许我们把外部文件编译进程序主体,称为程序不可分割的一部分,这就是传统意义上的程序资源(二进制资源)

​ WPF 中不仅支持传统的程序资源,还支持对象级资源,每个界面元素都可以携带自己的资源并可被自己的子级元素共享。 WPF 中模板、样式、主题就经常放在对象级资源里。 即 WPF 中,数据分为四个等级存储:

  1. 数据库里的数据:相当于存放在仓库
  2. 资源文件里的数据: 相当于存放在旅行箱
  3. 对象级资源里的数据:相当于随身携带的背包里
  4. 变量里的数据:相当于拿在手里

二、对象级资源的使用

对象级资源的声明与使用如下:

  <Window.Resources>
        <ResourceDictionary>
            <sys:String x:Key="Mystring">hello</sys:String>
            <sys:Double  x:Key="pi">3.1415926</sys:Double>
        </ResourceDictionary>
    </Window.Resources>
    <StackPanel>
        <TextBox Text="{StaticResource Mystring}"></TextBox>
    </StackPanel>

​ 在检索资源时,先查找控件自己的 Resource 属性,如果没有这个资源程序会沿着逻辑树向上一级控件查找,如果连最顶级的容器都没有这个资源,程序就会去查找 Application.Resource(也就是程序的顶级资源),如果还没找到,那就抛出异常。

​ 我们也可以像使用 CSS 和 JS 那样把资源放在独立的文件中,然后使用 ResourceDictonary 的 Source 属性去添加引用,如下,我们添加两个资源文件 “Dictionary1.xaml” 和 “Dictionary1.xaml”,然后在里面编写如下内容后引用到主界面上:

   <Style TargetType="Button" x:Key="D1ButtonStyle">
        <Setter Property="Foreground" Value="White"/>
    </Style>
  <Style x:Key="D2CommboBoxStyle" TargetType="ComboBox">
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Foreground" Value="#293f5f"/>
        <Setter Property="IsEditable"  Value="False"/>
        <Setter Property="IsReadOnly" Value="True"/>
        <Setter Property="Background" Value="Transparent"/>
    </Style>
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"></ResourceDictionary>
                <ResourceDictionary Source="Dictionary2.xaml"></ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
     <StackPanel>
        <Button  Margin="10" Height="50" Style="{StaticResource D1ButtonStyle}"></Button>
        <ComboBox Margin="10" Height="50" Style="{StaticResource D2CommboBoxStyle}"></ComboBox>
    </StackPanel>

三、StaticResource 和 DynamicResource 使用资源

StaticResource ,静态资源使用,指的是程序载入内存的时候对资源的一次性使用,后续就不会再去访问这个资源了。

DynamicResource,动态资源使用,指的是在程序运行过程中仍然会去访问资源。

如下例子,当我们点击 Update 按钮时,资源 “Mystring2”内容可以更新,但 “Mystring1” 就不能更新显示了:

 <Window.Resources>
      <ResourceDictionary>
                    <sys:String x:Key="Mystring1">hello</sys:String>
                    <sys:String x:Key="Mystring2">wpf</sys:String>
               </ResourceDictionary>
    </Window.Resources>
    <StackPanel>
        <TextBox Margin="10" Height="50" Text="{StaticResource Mystring1}"></TextBox>
        <TextBox Margin="10" Height="50" Text="{DynamicResource Mystring2}"></TextBox>
        <Button Margin="10" Height="50" Content="Update" Click="ButtonBase_OnClick"></Button>
    </StackPanel>
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            this.Resources["Mystring1"] = $"Test DateTime:{DateTime.Now.ToLongTimeString()}";
            this.Resources["Mystring2"] = $"Test DateTime:{DateTime.Now.ToLongTimeString()}";
        }

四、WPF 添加二进制资源

​ 传统的 Windows 程序中,会把程序必须使用的资源与应用程序自身打包在一起,这样就可以防止资源丢失或损坏(但会造成应用程序体积变大)。常见的程序资源有图标、图片、文本、音频、视频等,编译器把这些文件编译进目标文件(最终的 .exe 或 .dll 文件),资源文件在目标文件中以二进制数据的形式存在、形成目标文件的资源段(Resource 文件),使用数据时会被提取出来。

​ WPF 使用外部文件资源可以直接添加文件到程序集,然后使用 Pack URI 引用使用即可,Pack URI 相关内容可以阅读:WPF Pack URI

        <StackPanel Height="100" Orientation="Horizontal">
            <Image Source="pack://application:,,,/Images/1.jpg"></Image>
            <Image Source="Images/2.jpg"></Image>
        </StackPanel>

使用 Pack URI 路径需要注意:

  • Pack URI 使用 正斜线(/)表示路径
  • 使用缩略写法意味着相对路径,C# 代码中的 UriKind 必须为 Relative
  • 使用完整写法时是绝对路径,C# 代码中的 UriKind 必须为 Absolute,且代表根目录的 “/” 不能省略
  • 使用相对路径时可以借助类似 DOS 的语法进行导航,比如 “./”代表同级目录,“../”表示父级目录。
原文地址:https://www.cnblogs.com/dongweian/p/14393379.html