在前一个Post当中,我从资源编译行为的角度讨论了WPF中的资源。但是,不管是Resource还是Content都是在编译时声明资源。如果我们打破这个限制,不希望指定完全确认的资源地址。WPF提供了一种类似IE地址定位的抽象,它根据应用程序部署的位置决议。
WPF将应用程序的起源地点进行概念上的抽象。如果我们的应用程序位于http://yilinglai.cnblogs.com/testdir/test.application。我们应用程序的起源地点是http://yilinglai.cnblogs.com/testdir/,那么我们就可以在应用程序中这样指定资源位置: <Image Source=”pack://siteoforigin:,,,/Images/Test.JPG”/> 通过这种包装的Uri,使用资源的引用更加灵活。那么,这种类似Internet应用程序的资源包装Uri指定方式有什么优点呢? 1)、应用程序Assembly建立后,文件也可被替代。 2)、可以使文件只在需要使才被下载。 3)、编译应用程序时,我们不需要知道文件的内容(或者文件根本不存在)。 4)、某些文件如果被嵌入到应用程序的Assembly后,WPF将不能加载。比如Frame中的HTML内容,Media文件。 这里的pack://其实是一种URI(Uniform Resource Identifiers)语法格式。pack://<authority><absolute_path>,其中的authority部分是一个内嵌的URI。注意这个URI也是遵守RFC 2396文档声明的。由于它是被嵌入到URI当中,因此一些保留字符必须被忽略。在我们前面的例子中,斜线(”/”)被逗号(”,”)代替。其它的字符如”%”、”?”都必须忽略。 前面例子中的siteoforigin可以理解为一种authority的特例。WPF利用它抽象了部署应用程序的原始站点。比如我们的应用程序在C:\App,而在相同目录下有一个Test.JPG文件,访问这个文件我们可以用硬编码URI file:///c:/App/Test.JPG。另外一种方法就是这种抽象性:pack://siteoforigin:,,/Test.JPG。这种访问方法的便利是不言而喻的!在XPS文档规范中,对URI有更好的说明。有兴趣朋友可以在此下载。 也许你看到现在对此的理解有些问题。不用太着急,随着你对WPF越来越熟悉,会有更多的体会。对于WPF的新手(我也是),对于此点不必过度纠缠。因为WPF的Application类中提供了一些有用的方法: Application.GetResourceStream (Uri relativeUri); Application.GetContentStream(Uri relativeUri); Application.GetRemoteStream (Uri relativeUri); 通过使用这些函数,隐藏了URI定位的细节。从这些函数的名称我们可以看出,它们分别对应于我在前面介绍的三种类型:Content、Resource和SiteofOrigin。 最后,简单的说明一下另一种使用资源的方式,直接定义资源,不使用任何的属性,具体的用法看例子就明白了: <StackPanel Name="sp1"><StackPanel.Resources> <Ellipse x:Key="It1" Fill="Red" Width="100" Height="50"/> <Ellipse x:Key="It2" Fill="Blue" Width="200" Height="100"/> </StackPanel.Resources> <StaticResource ResourceKey="It1" /> <StaticResource ResourceKey="It2" /> </StackPanel> |
|