众所周知ASP.NET 2.0里对本地化(Localization)做了很多工作,大大简化了开发过程。今天终于能抽出时间研究一下这个技术了,资料很多,但大多带着一股咬文嚼字的翻译味道,So......自己写一篇。
1.使用工具自动生成本地化资源(LocalResources)
2.原来Localizable AttributeProperty是这么回事呀
3.手工添加本地化资源
4.显示使用本地化资源
5.全局资源的使用(GlobalResources)
6.如何在后台编程时使用这两种资源
7.编程切换语言设置
8.使用图片资源
9.代码下载
1.使用工具自动生成本地化资源(LocalResources)
首先当然是建立一个WEB工程啦,如图所示:
双击Default.aspx,切换到[设计]视图,从工具箱里拖一个Button进来。点击菜单中的[工具]->[生成本地资源],如图所示:
这时发现在解决方案方案视图里自动增加了一份本地资源,如下图所示:
切换到属性视图,可以看到Text和ToolTip都被加上了一个红色符号,提示“属性是用表达形式隐式绑定的”,如下图所示:( 注意:只有在视图状态下选中控件才能看到这两个属性哟)
为了增加对多语言的支持,我们现在右键Default.aspx.resx,点击复制,再选中App_LocalResources目录,点击粘贴,将“副本 Default.aspx.resx”重命名为Default.aspx.en-us.resx,如图所示:
分别编辑Default.aspx.resx和Default.aspx.en-s.resx 的内容,如下图示:
Default.aspx.resx
Default.aspx.en-s.resx
运行网站,效果如下图所示:
点击IE菜单的[工具]->[Internet 选项],在弹出的对话框中点[常规]选项卡的[语言]按钮,弹出[语言首选项]对话框,如下图所示:
点击[添加]按钮,选择英语(美国),并上移到第一位,如下图所示:
一路[确定]点下来,刷新页面,可以看到Button的标题变成“Hello World”啦,如下图所示:
综上所述,使用工具自动生成本地化资源,并隐式的绑定到控件上,来实现页面的本地化是非常简单的,但存在以下几项问题:
1)必须为每个页生成多份资源文件;
2)只有控件属性中被标识为Localizable(true)才可能被工具扫描到;
3)由于是对页面包含的控件进行扫描,所以最好是在页面布局基本确定后再使用该工具,并且在编辑完 资源文件后不要再使用该工具,如果不幸你这样做了。。。会发现默认的资源文件被清空了
2.原来Localizable AttributeProperty是这么回事呀
在我前天写的随笔 开发和使用自定义服务器控件中,一直对属性为什么要使用Localizable(true)不清楚。
1.使用工具自动生成本地化资源(LocalResources)
2.原来Localizable AttributeProperty是这么回事呀
3.手工添加本地化资源
4.显示使用本地化资源
5.全局资源的使用(GlobalResources)
6.如何在后台编程时使用这两种资源
7.编程切换语言设置
8.使用图片资源
9.代码下载
1.使用工具自动生成本地化资源(LocalResources)
首先当然是建立一个WEB工程啦,如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/1844c1692a9aca63e8eb3ee453d7509b.jpeg)
双击Default.aspx,切换到[设计]视图,从工具箱里拖一个Button进来。点击菜单中的[工具]->[生成本地资源],如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/1396025af534363c731f6c6a810045f6.jpeg)
这时发现在解决方案方案视图里自动增加了一份本地资源,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/367658a1d458fe4133ab72edd5ac7b7d.jpeg)
切换到属性视图,可以看到Text和ToolTip都被加上了一个红色符号,提示“属性是用表达形式隐式绑定的”,如下图所示:( 注意:只有在视图状态下选中控件才能看到这两个属性哟)
![](https://i-blog.csdnimg.cn/blog_migrate/6d9e5d37aa4fa13bae5a80e409dc8bcb.jpeg)
为了增加对多语言的支持,我们现在右键Default.aspx.resx,点击复制,再选中App_LocalResources目录,点击粘贴,将“副本 Default.aspx.resx”重命名为Default.aspx.en-us.resx,如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/24dee01d5200240fb2721592d432d858.jpeg)
分别编辑Default.aspx.resx和Default.aspx.en-s.resx 的内容,如下图示:
Default.aspx.resx
![](https://i-blog.csdnimg.cn/blog_migrate/fb0b252caa3b018d03d06bbfbb348279.jpeg)
Default.aspx.en-s.resx
![](https://i-blog.csdnimg.cn/blog_migrate/7a182c1d053dda3f383e18ee088678f5.jpeg)
运行网站,效果如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/8a9a2c2e5214ae672585185b07c3ad4c.jpeg)
点击IE菜单的[工具]->[Internet 选项],在弹出的对话框中点[常规]选项卡的[语言]按钮,弹出[语言首选项]对话框,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/d3b00da6438458305cee699e00d1e4ec.jpeg)
点击[添加]按钮,选择英语(美国),并上移到第一位,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/d132e2a00a7523291575f451a24a7f09.jpeg)
一路[确定]点下来,刷新页面,可以看到Button的标题变成“Hello World”啦,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/8a5d3a2df44c3dd9a59611b1ba7af4fb.jpeg)
综上所述,使用工具自动生成本地化资源,并隐式的绑定到控件上,来实现页面的本地化是非常简单的,但存在以下几项问题:
1)必须为每个页生成多份资源文件;
2)只有控件属性中被标识为Localizable(true)才可能被工具扫描到;
3)由于是对页面包含的控件进行扫描,所以最好是在页面布局基本确定后再使用该工具,并且在编辑完 资源文件后不要再使用该工具,如果不幸你这样做了。。。会发现默认的资源文件被清空了
2.原来Localizable AttributeProperty是这么回事呀
在我前天写的随笔 开发和使用自定义服务器控件中,一直对属性为什么要使用Localizable(true)不清楚。
[
Bindable( true ),
Category( " Appearance " ),
DefaultValue( " Hello " ),
Description( " The welcome message text. " ),
Localizable( true )
]
public virtual string Text
{
get
{
string s = ( string )ViewState[ " Text " ];
return (s == null ) ? " Hello " : s;
}
set
{
ViewState[ " Text " ] = value;
}
}
Bindable( true ),
Category( " Appearance " ),
DefaultValue( " Hello " ),
Description( " The welcome message text. " ),
Localizable( true )
]
public virtual string Text
{
get
{
string s = ( string )ViewState[ " Text " ];
return (s == null ) ? " Hello " : s;
}
set
{
ViewState[ " Text " ] = value;
}
}
查了许多关于WEB控件开发的资料,其中都对这个AttributeProperty做了忽略,原来只有当控件的属性声明为Localizable(true)时,VS的生成本地资源工具才会扫描到。
![](http://www.cnblogs.com/CuteSoft_Client/CuteEditor/images/emteeth.gif)
3.手工添加本地化资源
第一点中提到过生成本地资源工具只能扫描到页面已经包含的控件,那么如果后面由于开发需要又增加了一个新的控件要怎么办呢?虽然大部人都能自己想到,但还是写一下吧。
从工具箱再拖一个Label控件到页面上,切换到源视图,修改代码如下:
<
asp:Label
ID
="Label1"
runat
="server"
meta:resourcekey
="Label1Resource1"
Text
="Label"
></
asp:Label
>
再修改两份本地资源文件,为Label1添加Label1Resource1键值的相关资源,如下图所示:
Default.aspx.resx
![](https://i-blog.csdnimg.cn/blog_migrate/38157e381690aeae824b399ef63a16c1.jpeg)
Default.aspx.en-s.resx
![](https://i-blog.csdnimg.cn/blog_migrate/68f6f7598da3b1d58442ef9dd5316194.jpeg)
再运行程序,切换语言设置,可以看到Label1的效果和Button1是一样的,如图所示:
中文(中国)
![](https://i-blog.csdnimg.cn/blog_migrate/10b6d4181f4da35378e4fda5756bb9c6.jpeg)
英语(美国)
![](https://i-blog.csdnimg.cn/blog_migrate/1fed12e1eef4712b5fc0c1702f38d01c.jpeg)
4.显示使用本地化资源
OK,前面提到的都是隐式使用本地化资源,那么如何显示的使用本地化资源呢?相对于隐式来讲,显示更加灵活,功能也更强大。
只需要将刚才的Label1的代码,
<
asp:Label
ID
="Label1"
runat
="server"
meta:resourcekey
="Label1Resource1"
Text
="Label"
></
asp:Label
>
修改为,即可。
<
asp:Label
ID
="Label1"
runat
="server"
Text ="<%$ Resources:Label1Resource1.Text %>"
ToolTip ="<%$ Resources:Label1Resource1.ToolTip %>" >
</ asp:Label >
Text ="<%$ Resources:Label1Resource1.Text %>"
ToolTip ="<%$ Resources:Label1Resource1.ToolTip %>" >
</ asp:Label >
这时切换到[设计]视图,选中Label1控件,查看属性视图,会发现Text和ToolTip被加上的是蓝色的符号,提示“属性绑定了表达式”。跟上面提到的红色符号比较,少了“隐式”二字,这也就是所谓的显式和隐定的来源吧,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/f3a5b91e393026f379b8f81eb76ab66e.jpeg)
5.全局资源的使用(GlobalResources)
前面提到过,本地资源需要为每个页面分别生成多个资源文件,虽然这样看起来分门别类的挺清楚,但在实际应用过程中,我们有许多资源是可以共享的,总不能不停的重复写来写去吧。其实这种情况我们可以用全局资源(GlobalResources)来解决。
在资源方案视图中选中网站,右键,点击[添加ASP.NET 文件夹]->[App_GlobalResources],如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/a67c84edf4422a49663b4624b6ab9e7d.jpeg)
再选中App_GlobalResources文件夹,右键,点击[添加新项],在弹出的对话框中选中“资源文件”,命名为“LocalizedText.resx”,点击[添加],如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/0bc343a465740d8e222f12e778a31e15.jpeg)
双击LocalizedText.resx进行编辑,添加一条新的字符串资源,如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/de1706ae21edd8d0c10aabf1afac191a.jpeg)
复制LocalizedText.resx,粘贴到App_GlobalResources目录,重命名为LocalizedText.en-us.resx,双击进行编辑,添加一条新的字符串资源,如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/a93b4d6f98dfff26751b3d6da7cd54fc.jpeg)
打开Default.aspx,切换到[设计]视图,从工具箱拖一个TextBox控件到页面上。切换到[源]视图,修改代码:
<
asp:TextBox
ID
="TextBox1"
runat
="server"
Text
="<%$ Resources:LocalizedText, Msg1 %>"
></
asp:TextBox
>
运行程序,切换语言设置,可以看到全局资源的使用效果了,如图所示:
中文(中国)
![](https://i-blog.csdnimg.cn/blog_migrate/176d6a011b0f02508f6b8f6151612fc7.jpeg)
英语(美国)
![](https://i-blog.csdnimg.cn/blog_migrate/adf90e1b80ea81a2a7cc4df39212513e.jpeg)
注意:全局资源不能使用隐式声明。
6.如何在后台编程时使用这两种资源
前面提到的都是在网页中使用这两种资源,那么如何在后台使用这两种资源呢?
打开Default.aspx,切换到[设计]视图,从工具箱拖一个Localize控件(Literal 控件与 Label 控件类似,但 Literal 控件不允许对所显示的文本应用样式。可以通过设置 Text 属性,以编程方式控制在控件中显示的文本。)到页面上。双击Button1,添加以下实现
protected
void
Button1_Click(
object
sender, EventArgs e)
{
Localize1.Text = (String)GetLocalResourceObject( " Label1Resource1.Text " ) + " " +
(String)GetGlobalResourceObject( " LocalizedText " , " Msg1 " );
}
{
Localize1.Text = (String)GetLocalResourceObject( " Label1Resource1.Text " ) + " " +
(String)GetGlobalResourceObject( " LocalizedText " , " Msg1 " );
}
记得添上这个引用
using
System.Globalization;
运行程序,切换语言设置,可以看到和前面使用表达式调用资源的效果是一样的,如图所示:
中文(中国)
![](https://i-blog.csdnimg.cn/blog_migrate/82e9b370fd7d2990dad70388f61cb430.jpeg)
英语(美国)
![](https://i-blog.csdnimg.cn/blog_migrate/e55f1af9eb6aeb3dbdb36115b6868458.jpeg)
7.动态切换语言设置
以上的介绍都是通过IE浏览器获取语言设置,其实我们可以自己设置使用哪种语言。
1)通过在每个页面里的Page节指定
<%
@ Page Culture
=
"
en-us
"
UICulture
=
"
en-us
"
%>
如上所设,该页将使用en-us的语言设置。
注意:这只是个概要式写法,实际的页面中的Page一般都包含更多的属性。
2)通过在Web.Config里的globalization节指定
<
system
.web
>
< globalization Culture ="en-us" UICulture ="en-us" />
</ system.web >
< globalization Culture ="en-us" UICulture ="en-us" />
</ system.web >
3)当然还有一种就是通过编程动态切换语言设置啦,这也是实际项目中经常用到的方式
打开Default.aspx,切换到[源]视图,添加如下代码
<
a
href
="?currentculture=zh-cn"
>
中文(中国)
</
a
>
< a href ="?currentculture=en-us" > English(USA) </ a >
< a href ="?currentculture=en-us" > English(USA) </ a >
打开Default.aspx.cs,添加如下代码
String s;
protected override void InitializeCulture()
{
s = Request.QueryString[ " currentculture " ];
if ( ! String.IsNullOrEmpty(s))
{
// UICulture - 决定了采用哪一种本地化资源,也就是使用哪种语言
// Culture - 决定各种数据类型是如何组织,如数字与日期
Thread.CurrentThread.CurrentUICulture = new CultureInfo(s);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(s);
}
}
protected override void InitializeCulture()
{
s = Request.QueryString[ " currentculture " ];
if ( ! String.IsNullOrEmpty(s))
{
// UICulture - 决定了采用哪一种本地化资源,也就是使用哪种语言
// Culture - 决定各种数据类型是如何组织,如数字与日期
Thread.CurrentThread.CurrentUICulture = new CultureInfo(s);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(s);
}
}
记得添上这个引用
using
System.Threading;
运行程序,分别点击新增加的两个链接,效果如图所示:
中文(中国)
![](https://i-blog.csdnimg.cn/blog_migrate/a0fe1ca563403938e3f4a2ae022d6124.jpeg)
Enlish(USA)
![](https://i-blog.csdnimg.cn/blog_migrate/fac34be20b3eacca202a43a8ff780dd6.jpeg)
8.使用图片资源
分别编辑LocalizedText.resx和LocalizedText.en-su.resx,添加图片资源,如图所示:
LocalizedText.resx
![](https://i-blog.csdnimg.cn/blog_migrate/27e7dd58b72422b148e4bff680271627.jpeg)
LocalizedText.en-su.resx
![](https://i-blog.csdnimg.cn/blog_migrate/b1d4d3da631127e908dcfb61a74a2e0e.jpeg)
注意:当图形文件添加到图形资源里时,系统会自动去除扩展名并把“-”替换成“_”,如上图,我的文件名为“en-us-flag.png”添加到资源里变成了“en_us_flag”。
打开Default.aspx,切换到[设计]视图,从工具箱拖一个Image控件到页面上。打开Default.aspx.cs,添加如下代码
protected
void
Page_Load(
object
sender, EventArgs e)
{
Image1.ImageUrl = " ~/Image.aspx?currentculture= " + s;
}
{
Image1.ImageUrl = " ~/Image.aspx?currentculture= " + s;
}
选中网站右键,创建一个新的WEB窗体,命名为Image.aspx,编辑该页面,在Page节增加如下代码
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
Image.aspx.cs
"
Inherits
=
"
Image
"
Culture
=
"
auto
"
UICulture
=
"
auto
"
%>
注意:默认创建的WEB窗体的Page节,不包括Culture和UICulture这两个属性,一定要手工添上,切记!
打开Image.aspx.cs,添加如下代码
运行程序,分别点击两个链接,效果如图所示:
中文(中国)
![](https://i-blog.csdnimg.cn/blog_migrate/fc2980e25d671784b1565bab7177d278.jpeg)
English(USA)
![](https://i-blog.csdnimg.cn/blog_migrate/399626144c374900f4589032bce6f5a2.jpeg)
protected
override
void
InitializeCulture()
{
String s = Request.QueryString[ " currentculture " ];
if ( ! String.IsNullOrEmpty(s))
{
// UICulture - 决定了采用哪一种本地化资源,也就是使用哪种语言
// Culture - 决定各种数据类型是如何组织,如数字与日期
Thread.CurrentThread.CurrentUICulture = new CultureInfo(s);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(s);
}
}
protected void Page_Load( object sender, EventArgs e)
{
System.Drawing.Bitmap img = (System.Drawing.Bitmap)GetGlobalResourceObject(
" LocalizedText " ,
CultureInfo.CurrentCulture.Name.ToLower().Replace( " - " , " _ " ) + " _flag " );
System.IO.MemoryStream ms = new System.IO.MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Response.ClearContent();
Response.ContentType = " image/jpeg " ;
Response.BinaryWrite(ms.ToArray());
img.Dispose();
ms.Dispose();
ms.Flush();
}
{
String s = Request.QueryString[ " currentculture " ];
if ( ! String.IsNullOrEmpty(s))
{
// UICulture - 决定了采用哪一种本地化资源,也就是使用哪种语言
// Culture - 决定各种数据类型是如何组织,如数字与日期
Thread.CurrentThread.CurrentUICulture = new CultureInfo(s);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(s);
}
}
protected void Page_Load( object sender, EventArgs e)
{
System.Drawing.Bitmap img = (System.Drawing.Bitmap)GetGlobalResourceObject(
" LocalizedText " ,
CultureInfo.CurrentCulture.Name.ToLower().Replace( " - " , " _ " ) + " _flag " );
System.IO.MemoryStream ms = new System.IO.MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Response.ClearContent();
Response.ContentType = " image/jpeg " ;
Response.BinaryWrite(ms.ToArray());
img.Dispose();
ms.Dispose();
ms.Flush();
}
当然,别忘了添上这两个引用
using
System.Threading;
using System.Globalization;
using System.Globalization;