WPF应用程序使用资源及多语言设置学习

 

 

WPF资源

WPF资源使用其实的也是resources格式嵌入资源,默认的资源名称为"应用程序名.g.resources",不过WPF资源使用的pack URI来访问资源。

添加图像资源 

在解决方案资源管理器中包含一个图像资源(如data/img.png)的时候,默认是输出为资源文件的(生成操作=Resource),编译的时候作为资源编译到程序集中;

当在img.png的属性页中把"生成操作"属性设置为"内容",同时设置"复制到输出目录"属性为"如果较新则复制",则输出为内容文件,data/img.png会复制一份到程序集输出目录,这样无需编译就可以修改资源文件了。

此图片资源的uri链接为"/data/img.png",如<Image Name="image3" Source="/data/img.png" />

在资源字典中使用字符串

ResouceDictionary中可以添加各种类型资源,使用如下方法来保存字符串到资源字典中。资源字典默认情况下会被编译成baml保存到"应用程序名.g.resources"资源中,也可以修改输出为内容文件方法同上。

资源字典的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 ="rdstring1" > resource dictionary string. </ sys:String >
</ ResourceDictionary >

 

别忘了在app.xaml中添加这个资源字典的引用:

MergedDictionaries

 

xaml代码中使用此字符串:

< Label  Content =" {StaticResource rdstring1} "  Name ="label8"   />

 

代码中使用此字符串:

string  msg =  ( string )Application.Current.FindResource( " rdstring1 " );
MessageBox.Show(msg);

 

加载程序集中的WPF资源 

先准备一个WPF资源类库:新建一个程序集,默认创建的东西都删掉,添加上面的资源字典dictionary1.xaml到类库中,编译为ClassLibrary1.dll,使用Reflector工具检查发现这个类库中资源名为:ClassLibrary1.g.resources,内容为dictionary1.baml,ok准备完毕。 

主程序集中无需引用这个资源库,只需要放在同一个输出目录下即可,在代码中加载此资源并合并到Application中。 

加载代码(相对URI): 

var uri  =   new  Uri( " /ClassLibrary1;component/Dictionary1.xaml " , UriKind.Relative);
var res 
=  (ResourceDictionary)Application.LoadComponent(uri);
Application.Current.Resources.MergedDictionaries.Add(res);

 

加载代码(绝对URI): 

var uri  =   new  Uri( " pack://application:,,,/ClassLibrary1;component/Dictionary1.xaml " );
ResourceDictionary res 
=   new  ResourceDictionary {Source  =  uri};
Application.Current.Resources.MergedDictionaries.Add(res);

 

在XAML中直接加载:

< Application 
    
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class
="MySampleApp.app" >
    
< Application.Resources >
        
< ResourceDictionary >
            
< ResourceDictionary.MergedDictionaries >
                
< ResourceDictionary  Source ="pack://application:,,,/ClassLibrary1;component/Dictionary1.xaml"   />
            
</ ResourceDictionary.MergedDictionaries >
        
</ ResourceDictionary >
    
</ Application.Resources >
</ Application >

 

使用资源方法同上,注意,后加载的资源会替换掉已有资源中相同名字的资源。

 

StringTable资源

有时候又大量的字符串资源需要创建,string table文件则是建立此资源的快捷方式。

stringtable内容是一个文本文件,内容格式为key=value/r/n ...,如下所示:

Title=A Simple Application中文
String1=Simple string 中文
Message=Message

然后把文件扩展名修改为.restext,编码为UTF-8,这里命名为data/strings.restext,在程序中引用此文件,同时修改此文件属性为嵌入资源,如图所示:

 

编译,使用Reflector检查程序集资源会发现多了一个名"MySampleApp.data.strings.resources"的资源,资源内容就是前面创建的strings.restext的内容,如图所示:

 

读取字符串资源方法和前面一样,只需要指定好资源的命名空间即可。

var rm2  =   new  ResourceManager( " MySampleApp.data.strings " , Assembly.GetExecutingAssembly());
label6.Content 
=  rm2.GetString( " String1 " );

最近学习dotnet多语言资源的设置,很多地方没有搞清楚,于是参考msdn写了点代码验证下想法。

测试程序是一个wpf默认程序,语言和资源均不做设置。

字符串资源

在默认资源文件中添加一条string1=teststring,编译之后用工具查看程序集可以发现字符串资源保存在名为"MySampleApp.Properties.Resources.resources"的资源中,其中MySampleApp为程序集的命名空间,"Properties.Resources"是默认资源文件的名称,".resources"是资源扩展名。

读取此字符串资源代码如下:

// 直接调用资源编辑器生成的类方法
Mywindow.Title  =   MySampleApp.Properties.Resources.string1;

// 或者使用通用方法
var rm  =   new  ResourceManager( " MySampleApp.Properties.Resources " , Assembly.GetExecutingAssembly());
Mywindow.Title 
=  rm.GetString( " string1 " );

 

读取字符串资源的xaml代码如下: 

< StackPanel  Name ="root"
           xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:res
="clr-namespace:MySampleApp.Properties"
           x:Class
="MySampleApp.MyPage" >
< TextBlock  Name ="Text1"  Text ="{x:Static res:Resources.string1}" ></ TextBlock >
</ StackPanel >

 

 注意如果想让上面的xaml代码能正常读取系统默认字符串资源,需要设置资源访问属性为public,如图所示:

WPF应用程序使用资源及多语言设置学习_第1张图片 

图片资源

在资源编辑器中添加一个png图片,名为img,资源中的图片格式为System.Drawing.Bitmap。 

读取img就是调用rm.GetObject("img"),返回对象是Bitmap类型,此对象无法直接用在WPF的Image控件上,必须做一些转换工作,转换Bitmap为BitmapImage.

var rm  =   new  ResourceManager( " MySampleApp.Properties.Resources " , Assembly.GetExecutingAssembly());          
var bmp 
=  rm.GetObject( " img " as  Bitmap;
var stream 
=   new  MemoryStream();
var bi 
=   new  BitmapImage();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
bi.BeginInit();
bi.StreamSource 
=  stream;
bi.EndInit();
image1.Source 
=  bi;

 

第二种方法:转换Bitmap为BitmapSource.

IntPtr bmpPt  =  bmp.GetHbitmap();
System.Windows.Media.Imaging.BitmapSource bitmapSource 
=  System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
    bmpPt, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
bitmapSource.Freeze();
DeleteObject(bmpPt);
image1.Source 
=  bitmapSource;

[System.Runtime.InteropServices.DllImport(
" gdi32.dll " )]
private   static   extern   int  DeleteObject(IntPtr o);

你可能感兴趣的:(image,String,application,语言,WPF,Dictionary)