5. 转载的
资源的应用
前变也已经说过可以引用别的程序集的资源,那么到底如何引用呢?另外,我们都是在说XAML中引用资源,那么代码中又该如何去做呢?我们又通常会在什么地方定义资源呢?这里就来说一下这几个问题,以及某些特殊情况下的定义。
· 共享资源
默认情况下,当有一个资源被引用到多个地方是,使用的都是同一个对象实例,这通常是理想的行为。但你同样也可以把x:Shared=”False”来让每个引用资源的地方都生成一个不同的对象实例,这样可以独立进行修改。这通常用于多逻辑资源的声明。
· 程序代码中定义和应用资源
在代码中定义一个新的Resource,你需要首先得到一个ResourceDictionary的实例,然后再创建一个新的资源并将这个资源加入到ResourceDictionary的实例中。而在访问资源时,你需要用到myWindow.Resources[“key”]或者object.FindResource(key)函数。注意myWindows是你当前window的实例,而在用FindResource时,前边的object代表的是这个资源所在的ResourceDictionary的父对象。
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Window3 window = new Window3();
window.Resources.Add("buttonBackground", newSolidColorBrush(Color.FromRgb(0,255,0)));
window.Resources.Add("borderBrush", new SolidColorBrush(Color.FromRgb(255, 0, 0)));
btnContent.Background = (Brush)window.FindResource("buttonBackground");
btnContent.BorderBrush = (Brush)window.FindResource("borderBrush");
}
|
注意在找不到资源时会抛出一个ResourceReferenceKeyNotFoundException异常,所以尽量调用TryFindResource方法更好些,如果失败将会返回null.
上边的例子是针对StaticResource来说的,它就相当于这段代码:
<Button x:Name="btnContent" Canvas.Left="50"
Background="{StaticResource buttonBackground}"
BorderBrush="{StaticResource borderBrush}" Content="Content" />
|
|
但对于DynamicResource来说,需要调用这个元素的SetResourceReference方法来更新依赖属性的绑定。下边的两端代码是相等的:
<Button x:Name="btnContent" Canvas.Left="50"
Background="{DynamicResource buttonBackground}"
BorderBrush="{ DynamicResource borderBrush}" Content="Content" />
|
btnContent.SetResourceReference(Button.BackgroundProperty, "buttonBackground");
btnContent.SetResourceReference(Button.BorderBrushProperty, "borderBrush");
|
SetResourceReference是可以在资源被加载到某个Resource Dictionary之前调用的,即便是FindResource会失败,但引用的建立仍然有效。
· 从另一个程序集中访问嵌入式资源
除了可以用特定的URI来访问别的程序中的二进制资源外,WPF可以从另外一个程序集中获取逻辑资源,这得用到ComponentResourceKey标记。要使用ComponentResourceKey,每个资源都必须有一个键名。然后你可以通过这样的方式访问:
<Button Background=”{DynamicResource {x:Static otherAssembly: MyClass.MyClassBrushKey }}” />
|
· Styles 和 Implicit Keys
样式是最常见的一种资源,而且它总是被定义在Resource Dictionary中,为了来重用。Style其实就是一系列分组的Setter的集合,用来设定逻辑资源的属性值,它有一种比较特殊的情形就是Implicit Keys,可以不声明一个x:Key的名字,而只设置x:TargetType的值,这样面对的就是对于所有这个类型的控件都使用这个样式。下边的示例中x:Key的值其实就是type-Button。
<Style TargetType="Button">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="AliceBlue"/>
<GradientStop Offset="1.0" Color="Salmon"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="18"/>
</Style>
|
Style也是资源的一种---从某种意义上来说,它很类似于我们给普通HTML中的元素建立CSS. 对于Designer来说可能轻松一些哦。
6. Resource Dictionary –资源字典
所有的资源项在最终都会被整合到Resource Dictionary中的,也就是说无论是FrameworkElement的Resources,还是Window的Resources,还是Application的Resources,还是特定的ResourceDictionary中定义的resources在整个应用编译执行的时候实际上他们都在一起的作为可遍历集合共同存在于一个相对会话空间内的。
我们也提到过Resource的key是可以被允许有相同的,这样在遍历不同相对地址的Resource Dictionary时会根据StaticResource或者DynamicResource的lookup behavior来确定哪个有效。通常为了维护和灵活性的考虑,我们通常会将Resource Dictionary文件分成好几个,但在某些场合下我们只需要用其中某些资源,那么我么可以将资源从几个独立的文件中提取并合并,那么可以这么做:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Diction1.xaml"></ResourceDictionary>
<ResourceDictionary Source="Diction2.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
|
注意,在资源合并后,仍然会出现重复值的情况,那么最后取出的资源获胜。
7. Localization – 本地化
本地化和换肤其实都是在用ResourceDictionary来做文章的。说白了,Localization就是用不同语言下取不同事先设定好的资源来显示而已。要做到这些很容易,4步就可以轻松实现:
· 定义Resource Dictionary来包含不同语言下要显示的资源项。
创建单独的Resource Dictionary文件,并以语言本身名字来命名,并把en-US来作为默认语言环境(这里顺便就命名为default.xaml了)
Default.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="Title_PM">Project Manager</sys:String>
<sys:String x:Key="Title_PL">Project Lead</sys:String>
<sys:String x:Key="Title_SD">Senior Developer</sys:String>
<sys:String x:Key="Title_SA">System Architecture</sys:String>
</ResourceDictionary>
|
zh-CN.xaml (注意对.NET命名空间的引用)
<ResourceDictionaryxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="Title_PM">项目经理</sys:String>
<sys:String x:Key="Title_PL">项目主管</sys:String>
<sys:String x:Key="Title_SD">资深开发工程师</sys:String>
<sys:String x:Key="Title_SA">系统架构师</sys:String>
</ResourceDictionary>
|
· 给应用程序添加默认资源:其实就是将默认的Resource Dictionary加入到Application的全局Resource里边。
<Application x:Class="WpfApplication1.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="Language\default.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
|
· 在Application启动时根据不同语言来加载以语言命名的XAML文件(Resource Dictionary)。因为对于重名的资源,后来加载的资源将会胜出,所以以当前语言名加载的XAML文件中的资源项将会被引用。这就是多语言的本质!
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
LoadLanguage();
}
private void LoadLanguage()
{
CultureInfo currentCultureInfo = CultureInfo.CurrentCulture;
ResourceDictionary langRd = null;
try
{
langRd = Application.LoadComponent(
new Uri(@"Language\" + currentCultureInfo.Name + ".xaml", UriKind.Relative)) asResourceDictionary;
}
catch
{
}
if (langRd != null)
{
if (this.Resources.MergedDictionaries.Count > 0)
{
this.Resources.MergedDictionaries.Clear();
}
this.Resources.MergedDictionaries.Add(langRd);
}
}
}
|
· 在XAML中引用资源。
<TextBlock Canvas.Top="50" Width="100" Height="24" Text="{StaticResource Title_PM}" />
|
· 大功告成,运行程序你会看到默认的语言的显示:Project Manager.当然如果你的默认文化是英语的话。用程序换成中文试试结果?没问题,在LoadLanguage()之前更改语言即可:
base.OnStartup(e);
CultureInfo info = new CultureInfo("zh-CN");
Thread.CurrentThread.CurrentCulture = info;
Thread.CurrentThread.CurrentUICulture = info;
LoadLanguage();
|
简单吧?呵呵。有关Resource的东西基本上就这么多了,换肤我们再开辟另一个话题来谈吧。这可是WPF够炫的Feature之一哦。。。。
分享到:
相关推荐
Windows Vista培训系列课程(10):WPF之资源处理
WPF 列表选择,动态调用ResourceDictionary内资源
VS2008 WPF经典教程-WPF资源......
wpf-资源的使用-resource
winform调用全局wpf资源样式,可以调用相对路径的xaml也可以调用绝对路径的xaml。
利用资源字典和资源文件来实现项目的多语言功能。资源字典实现窗体文字语言转换,资源文件实现MessageBox文字语言转换
WPF引入了统一资源标识Uri(Unified Resource Identifier)来标识和访问资源。其中较为常见的情况是用Uri加载图像。Uri加载图像资源有多种方式,可从外部文件夹中加载,也可以直接引用工程的资源图片……
WPF资源文件在DLL中的用法 把资源文件压缩到DLL中。 两种方式访问! 在主程序中调用方法!
官方实例,WPF实例程序,命令,动画,资源,样式及模板,本地化,拖拽,绑定,希望对初学WPF的童鞋有用...
通常使用 WPF 资源作为重用通常定义的对象和值的简单方法。例如定义一种可以复用的单色的Brush对象,按钮的背景及矩形的填充颜色均使用此Brush。。。。。。 (更多资源:http://cleopard.download.csdn.net/) (福利:...
压缩包里包括WPF的视频资源和WPF的文档资料,满足入门学习,欢迎下载使用,
Wpf 加载 Cur资源,一个简单的源码操作
本文告诉大家如何在 WPF 获取资源文件包含 # 号的文件资源
程序是面对客户使用的,不得不考虑多语言环境。该案例通过资源字典加绑定的方式实现语言动态切换。
vs2010版本。组件资源,对象资源:对象资源之资源集和 对象资源之静态和动态资源 对象资源之编程访问资源 对象资源之应用程序资源 对象资源之系统资源: 对象资源之资源字典的使用方式
c# WPF实现Windows资源管理器(附源码).docx
在WPF 资源文件内嵌入个性化字体。
学习wpf的优秀资源,有学习的小盆友可以看看。精辟分析WPF源代码,洞察功能背后隐藏的深刻设计理念。
wpf打印资源集合,一些代码汇总.做个备份.