原文:WPF之神奇的资源

WPF中的资源有两种,一种称为"程序集资源"(assembly resource),另一种称为"对象资源"(object resource)也称为"逻辑资源",WPF中统称后者为"逻辑资源"。

一、程序集资源
应用程序中的XAML、图片、音频、视频等文件,都可以将其作为程序集资源组织起来。
程序集资源可以以以下3种方式打包:
1.资源文件(Resource File):直接嵌入到程序集中。
2.内容文件(Content File):该文件的相关信息会编译到程序集中,如文件的相对位置。
3.Site of Origin文件:不参加编译,应用程序不知道该文件是否存在。

资源文件
向项目中添加一个jpg的图片,默认的Build Action就为Resource,在Xaml中的2种使用方式如下:

        <Image Source="1.jpg" />
<Image Source="pack://application:,,,/1.jpg"/>

答疑:
属性中的Build Action中有一个Embedded Resource和Resource,区别呢?
两者都可以将文件编译到程序集资源中去,前者用于Winform项目中嵌入程序集资源,在WPF中则选择后者。

内容文件
右键文件设置Build Action属性为Content,同时设置属性Copy to Output Directory 设置为Copy always或者Copy if newer,则可以复制到bin\debug下。

     <Image Source="Images/1.jpg"></Image>
<Image Source="/Images/2.jpg" Grid.Row="1"></Image>

以上两个方式均可以显示输出为Content的图片。

Site of Origin文件
Site of Orign文件根本不参加编译,应用程序编译时候不知道该文件是否存在,只有运行时候才知道。
配置此类文件,右键属性设置Build Actoin为None,Copy to Output Directory设置为Copy always或者Copy if newer。通过代码访问需要使用GetRemoteStream方法。

        Uri uri = new Uri("/siteoforiginfile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetRemoteStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.siteoforiginfileframe.Content = page;

Uri语法
Uri可以通过当前程序集、被引用的程序集、相对程序集的一个位置和任意位置标识访问资源。
WPF中的Uri由3部分组成,第一个部分的协议是pack;第2个部分成为"authority",有两种值:一是application://,表示编译时知道的文件,主要指资源和内容文件;二是siteoforign://,表示Site of Origin文件;第3部分是路径,如果是引用程序集中资源,情况会稍微复杂一点。路径必须包含引用的程序集名称和一个Component标识,表示引用的不是本地程序集的资源,有时还需要加上版本信息。
WPF中的路径分为相对和绝对路径。WPF中的默认Uri设置是pack://application:,,,,因此引用site of orign文件必须要使用绝对路径。

pack://application:,,,/ResourceFile.xaml
/ResouceFile.xaml

第一种为绝对路径,第二种为相对路径。

 <DockPanel>
<StackPanel DockPanel.Dock="Top"> <GroupBox Header="Absolute Pack URIs">
<StackPanel>
<Frame Source="pack://application:,,,/ResourceFile.xaml" />
<Frame Source="pack://application:,,,/Subfolder/ResourceFile.xaml" />
<Frame Source="pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml" />
<Frame Source="pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml" />
<Frame Source="pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml" />
<Frame Source="pack://application:,,,/ContentFile.xaml" />
<Frame Source="pack://application:,,,/Subfolder/ContentFile.xaml" />
<Frame Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />
<Frame Source="pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml" />
</StackPanel>
</GroupBox> <GroupBox Header="Relative Pack URIs">
<StackPanel>
<Frame Source="/ResourceFile.xaml" />
<Frame Source="/Subfolder/ResourceFile.xaml" />
<Frame Source="/ReferencedAssembly;component/ResourceFile.xaml" />
<Frame Source="/ReferencedAssembly;component/Subfolder/ResourceFile.xaml" />
<Frame Source="/ReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml" />
<Frame Source="/ContentFile.xaml" />
<Frame Source="/Subfolder/ContentFile.xaml" />
<Frame Source="pack://siteoforigin:,,,/SiteOfOriginFile.xaml" />
<Frame Source="pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml" />
</StackPanel>
</GroupBox> </StackPanel> <GroupBox Header="Version-Specified Pack URIs">
<DockPanel>
<Button DockPanel.Dock="Top" Click="click0">Get Resource File in Reference Assembly v1.0.0.0</Button>
<Button DockPanel.Dock="Top" Click="click1">Get Resource File in Reference Assembly v1.0.0.1</Button>
<Frame Name="frame" NavigationUIVisibility="Hidden" />
</DockPanel>
</GroupBox> </DockPanel>
   void click0(object sender, RoutedEventArgs e) {
Uri uri = new Uri("/VersionedReferencedAssembly;v1.0.0.0;component/ResourceFile.xaml", UriKind.RelativeOrAbsolute);
this.frame.Source = uri;
} void click1(object sender, RoutedEventArgs e)
{
Uri uri = new Uri("/VersionedReferencedAssembly;v1.0.0.1;component/ResourceFile.xaml", UriKind.RelativeOrAbsolute);
this.frame.Source = uri;
}

此示例为微软提供的Uri的用法,几乎涵盖了所有的使用方法,源码下载如下:
WPFUriSample


WPF中的URI处理顺序
WPF中有两个处理系统,即siteoforigin:///和applicatoin:///,前者按照提供的路径查找SiteofOrigin文件,后者的比较复杂:
1。先查找路径是否为内容文件
2.如果未找到,则继续在程序集的资源中查找;如果找到则为资源问及那;
3.如果未找到,则为无效。

逻辑资源(对象资源)
看如下例子:

    <Window.Resources>
<ImageBrush x:Key="TileBrush" x:Shared ="True" TileMode="Tile"
ViewportUnits="Absolute" Viewport="0 0 32 32"
ImageSource="happyface.jpg" Opacity="0.3" ></ImageBrush>
</Window.Resources>
  <Button Background="{StaticResource TileBrush}" Padding="5"
FontWeight="Bold" FontSize="14" Margin="5" Click="Button_Click">A Tiled Button 静态资源引用</Button>

以上例子在Resource中定义了一个画刷资源,在Button中使用其设置背景颜色,通过"{StaticResouce ReourceKey}"语法进行资源的引用。

不仅仅画刷(或者是应用于样式)可以作为资源,普通的.Net对象也可用于资源,如下:

xmlns:s ="clr-namespace:System;assembly=mscorlib"

在Windows标签中引用System命名空间,使用如下:

    <Window.Resources>
<s:String x:Key="ButtonContent">
逻辑资源Demo
</s:String>
</Window.Resources>

调用资源,作为文本显示

<Button Grid.Row="2" Margin="5" Content="{StaticResource ButtonContent}" Click="Button_Click_1" />

静态资源和动态资源

WPF提供了两种访问逻辑资源的方式,一是静态资源,通过StaticResource标记扩展来实现,前面引用资源的方式均为此方式;二是动态资源,通过DynamicResource标记扩展
来实现。
静态资源和动态的资源主要区别在于,静态资源只从资源字典中查找一次资源,后者在应用程序需要时查找资源.

<Button Background="{StaticResource TileBrush}" Padding="5"
FontWeight="Bold" FontSize="14" Margin="5" Click="Button_Click">A Tiled Button 静态资源引用</Button>
<Button Grid.Row="1" Background="{DynamicResource TileBrush}" Padding="5"
FontWeight="Bold" FontSize="14" Margin="5" Click="Button_Click">A Tiled Button 动态资源引用</Button> <Button Grid.Row="3" Margin="5"Click="Button_Click" />

例子中的两个按钮一个是静态资源方式引用,一种是动态资源方式引用,在Click中修改资源如下:

            ImageBrush brush = (ImageBrush)this.Resources["TileBrush"];
ImageBrush newbrush = brush.Clone();
newbrush.Viewport = new Rect(, , , );
this.Resources["TileBrush"] = newbrush;

点击按钮会神奇的发现,动态资源方式的按钮的背景会变化哦.
注意:切忌,最后一句代码,必须要重新给旧的资源对象赋值.

共享资源
默认情况下,当有一个资源被应用到多处时使用的都是一个对象实例,这是极好的了.如果希望应用程序在使用资源的每处都有一个不同的对象实例,可以在资源中标记
x:Shared="False".
例如将Image作为资源,由于其派生自Visual类,会被添加到逻辑树和可视化树中,因此不能将Image的对象作为资源多次使用,否则会抛出异常哦.但是可以将Image资源
标记成x:Shared="False",这样在应用这个资源时实际创建了不同的对象实例。

使用ResourceDictionary组织管理资源
WPF中提供了ResourceDictionary(资源字典)类型的XAML文件组织资源,右键项目ADD菜单-->Resource Dictionary即可创建一个资源字典,资源可以分类别
放在同一个资源文件。如下降画刷资源放在Brushes.xaml文件中:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local ="clr-namespace:mumu_resourcesLib">
<ImageBrush
x:Key="SadFaceBrush"
TileMode="Tile"
ViewportUnits="Absolute" Viewport="0 0 32 32"
ImageSource="sadface.jpg" Opacity="0.3">
</ImageBrush>
</ResourceDictionary>

在App.xaml文件中通过MergedDictionaries包含资源字典文件,这样应用程序就可以访问Brushes.xaml文件中的资源了:

<Application x:Class="mumu_shareresources.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Brushes.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

使用如下:

 <Button Background="{StaticResource SadFaceBrush}" />

程序集之间共享资源:
有如下目录结构的程序

ResourceDemo项目为WPF Application,ResourceLibrary为WPF Libiary。在ResourceLibrary中有Brushes.xaml资源文件,代码如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ImageBrush
x:Key="SadFaceBrush"
TileMode="Tile"
ViewportUnits="Absolute" Viewport="200 200 200 200"
ImageSource="1.jpg">
</ImageBrush>
</ResourceDictionary>

在APP.xaml中引用资源文件:

<Application x:Class="WpfApplication9.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourceLibrary;component/Brushes.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

程序集之间引用使用"/程序集;component/资源文件"这样的语法来进行调用。
使用方法还是这样:

 <Button Background="{StaticResource SadFaceBrush}"></Button>

好了,WPF的资源介绍暂且到这里,欢迎大家讨论分享.



WPF之神奇的资源的更多相关文章

  1. (转)WPF控件开源资源

    (转)WPF控件开源资源 Textbox Drag/Drop in WPFhttp://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in- ...

  2. WPF笔记(1.8 资源与映射)——Hello,WPF!

    原文:WPF笔记(1.8 资源与映射)--Hello,WPF! 终于,看明白了,已经是凌晨1:39分.这本书这一节写得实在是不好,一个local搞得我糊里糊涂,于是,准备按照他的思路,按照我的理解,改 ...

  3. WPF中静态引用资源与动态引用资源的区别

    WPF中静态引用资源与动态引用资源的区别   WPF中引用资源分为静态引用与动态引用,两者的区别在哪里呢?我们通过一个小的例子来理解. 点击“Update”按钮,第2个按钮的文字会变成“更上一层楼”, ...

  4. WPF控件开源资源

    (转)WPF控件开源资源 Textbox Drag/Drop in WPFhttp://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in- ...

  5. WPF中引入外部资源

    有时候需要在WPF中引入外部资源,比如图片.音频.视频等,所以这个常见的技能还是需要GET到. 第一步:在VS中创建一个WPF窗口程序 第二步:从外部引入资源,这里以引入图片资源为例 1)新建Reso ...

  6. WPF 精修篇 管理资源字典

    原文:WPF 精修篇 管理资源字典 样式太多  每个界面可能需要全局的样式 有没有肯能 WPF 中的样式 像Asp.net中 的CSS一样管理那 有的 有资源字典 BurshDictionary &l ...

  7. WPF 精修篇 动态资源

    原文:WPF 精修篇 动态资源 动态资源 使用 DynamicResource 关键字 静态 就是 StaticResource 原则上是 能用静态就用静态 动态会让前台界面压力很大~ 动态资源引用 ...

  8. WPF 精修篇 静态资源

    原文:WPF 精修篇 静态资源 在WPF中 如果设置好了一个控件样式或者矩形样式 如果Copy出一个新的 那么样式也会双份 比如 下面的矩形 我定义好了一个 Copy 以后 就出现一个新的 但是改变样 ...

  9. WPF之命名空间和资源

    1.参考: https://msdn.microsoft.com/zh-cn/library/ms747086(v=vs.110).aspx http://www.cnblogs.com/cww201 ...

随机推荐

  1. git仓库搭建

    第一步安装git [root@Centos-node2 ~]# yum -y install git 第二步创建git用户 [root@Centos-node2 ~]# useradd git [ro ...

  2. Java Web学习总结(8)——使用Cookie进行会话管理

    一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...

  3. 就目前市面上的面试整理来说,最全的BAT大厂面试题整理在这

    原标题:就目前市面上的面试整理来说,最全的BAT大厂面试题整理在这 又到了面试求职高峰期,最近有很多网友都在求大厂面试题.正好我之前电脑里面有这方面的整理,于是就发上来分享给大家. 这些题目是网友去百 ...

  4. HttpClient证书回调问题解决

    /// <summary>        /// httpclient请求        /// </summary>        /// <param name=&q ...

  5. 8.3 Android灯光系统_编写HAL_lights.c

    注意在led-classes.c中定义的led_class_attrs[]所建立的文件的属性应该改为0666,否则应用程序无权操作它 同时ledtrig-time.c里面对应新建的那几个delay_o ...

  6. 07_android入门_採用HttpClient的POST方式、GET方式分别实现登陆案例

    1.简单介绍 HttpClient 是 Apache Jakarta Common 下的子项目,能够用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,而且它支持 HTTP 协议 ...

  7. [MobX] MobX fundamentals: deriving computed values and managing side effects with reactions

    Derivations form the backbone of MobX and come in two flavors: computed values are values that can b ...

  8. Java文档上传问题设计

    近期公司让做一个文档上传的功能,功能描写叙述大概是这样子滴 书籍名称.书籍定价.书籍封面图片(须要上传).文档内容 (须要上传) .还有其它相关的描写叙述信息. 我的设计  表 A  包括以上字段 , ...

  9. css3-10 css3中的边框样式有哪几种

    css3-10 css3中的边框样式有哪几种 一.总结 一句话总结:1.border-radius 2. box-shadow 3.border-image三种,box一种border两种 1.css ...

  10. jquery如何实现点击标题收缩下面的内容

    jquery如何实现点击标题收缩下面的内容 一.总结 一句话总结:怎么做复杂前端任务,先把样式(最简单)做出来,然后在写js. 1.如何取jquery集合中的某个索引号的元素? 不是get(),是eq ...