不给我分配任务,自己看在开发的项目代码,现在在做的项目支持多语言功能,就是用户通过切换语言选项,实现页面的中英文等语言之间的切换,是前辈开发好的,觉得这是个很高深的技术,不过还是想尝试学一下。
开始想从项目代码中抽出相关代码来实现,但是项目代码太多了,对代码的结构理解不好,绕晕了。只好,借用网络代码。
主要参考资料:ASP.NET 2.0中实现多语言界面的方法
DynamicWebMultiLanguages
1. 和以前用同样的方法做一个界面,只是需要注意一点,所有需要用多语言来显示的文字都要用Label来做,不能直接写在页面上。
2. 做完之后,在Solution Explorer里选中这个文件,选Tools->Generate Local Resource,会自动生成一个目录文件夹App_LocalResources,目录中有个resx文件,比如你的aspx文件叫MultiLanguag.aspx,它就叫MultiLanguag.aspx.resx,打开这个文件,会发现界面上的控件都在这里。
3. 再打开原来的aspx文件看看,会发现源码变了,头文件和控件代码都多了个meta:resourcekey
4. 现在要做的工作就是,把aspx.resx文件copy一下,然后paste,想要几种语言就paste几下,然后rename,格式是XXXXX.aspx.fr-fr.resx,这里fr-fr是你要做的语言的名字。比如英语就是XXXx.aspx.en-us.resx,汉语就是XXXX.aspx.zh-cn.resx。其他不知道的语言,可以到打开IE->tools->internet options -> languages -> add中去查。
5. 到这里,前台就完成了,下面要写后台代码了。
先建立一个类,管理语言,叫LanguageManagement.cs
LanguageManagement
using System.Threading;
using System.Globalization;
using System.IO;
using System.Collections.Generic;
/// <summary>
/// Summary description for LanguageManagement
/// </summary>
public sealed class LanguageManagement
{
public static readonly CultureInfo DefaultCulture=new CultureInfo("en-us");
public static readonly CultureInfo[] AvailableCultures;
static LanguageManagement()
{
//
// TODO: Add constructor logic here
//
List<string > availableResources=new List<string>();
string resourcepath=Path.Combine(System.Web.HttpRuntime.AppDomainAppPath,"App_LocalResources");
DirectoryInfo dirInfo = new DirectoryInfo(resourcepath);
foreach(FileInfo fi in dirInfo.GetFiles("*.*.resx",SearchOption.AllDirectories))
{
string cultureName=Path.GetFileNameWithoutExtension(fi.Name);
if(cultureName.LastIndexOf(".")==cultureName.Length-1)
continue;
cultureName=cultureName.Substring(cultureName.LastIndexOf(".")+1);
availableResources.Add(cultureName);
}
List<CultureInfo> result=new List<CultureInfo>();
foreach(CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
{
if(availableResources.Contains(culture.ToString()))
{
result.Add(culture);
}
}
AvailableCultures=result.ToArray();
CurrentCulture = DefaultCulture;
if(!result.Contains(DefaultCulture)&&result.Count>0)
{
CurrentCulture = result[0];
}
}
public static CultureInfo CurrentCulture
{
get
{
return Thread.CurrentThread.CurrentCulture;
}
set
{
Thread.CurrentThread.CurrentUICulture=value;
Thread.CurrentThread.CurrentCulture=value;
}
}
}
现在,可以加任何所需要的语言资源文件。因为这个类可能需要用在很多个页面上,为了减少重复代码,建立一个PageBase类,让页面继承此类。这里,用Session保存选择的语言状态。
PageBase
using System.Globalization;
/// <summary>
/// Summary description for PageBase
/// </summary>
public class PageBase:Page
{
private const string SESSION_KEY_LANGUAGE="CURRENT_LANGUAGE";
protected override void InitializeCulture()
{
base.InitializeCulture();
if(Session[SESSION_KEY_LANGUAGE]!=null)
{
ApplyNewLanguage((CultureInfo) Session[SESSION_KEY_LANGUAGE]);
}
}
private void ApplyNewLanguage(CultureInfo culture)
{
LanguageManagement.CurrentCulture=culture;
Session.Add( SESSION_KEY_LANGUAGE,LanguageManagement.CurrentCulture);
}
protected void ApplyNewLanguageAndRefreshPage(CultureInfo culture)
{
ApplyNewLanguage(culture);
Response.Redirect(Request.Url.AbsoluteUri);
}
public PageBase()
{
//
// TODO: Add constructor logic here
//
}
}
这里,就可以在页面的aspx.cs文件中,继承PageBase类了。
Page
using System.Globalization;
public partial class MultiLanguge : PageBase
{
string selectLanguage = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void lbtnEn_Click(object sender, EventArgs e)
{
selectLanguage = "en-us";
Session["SESSION_KEY_LANGUAGE"] = selectLanguage;
ApplyNewLanguageAndRefreshPage( new CultureInfo(selectLanguage));
//Response.Redirect(Request.Url.ToString());
}
protected void lbtnCh_Click(object sender, EventArgs e)
{
selectLanguage = "zh-cn";
Session["SESSION_KEY_LANGUAGE"] = selectLanguage;
ApplyNewLanguageAndRefreshPage( new CultureInfo( selectLanguage));
//Response.Redirect(Request.Url.ToString());
}
}
做了个简单的页面,通过切换中英文的button,功能实现了!
虽然,代码都是抄写网上的,不是很理解,但是实现了功能,还是很有成就感的。
哈哈!
相关知识点:
1. readonly
http://blog.csdn.net/yunggood/archive/2009/01/21/3847439.aspx
readonly和const都是表示常数,const字段是编译时常数,readonly字段可用于运行时常数。const对于引用类型的常数,可能的值只能是string和null,readonly可以是任何类型。
2. CultureInfo
属于System.Globalization命名空间,System.Globalization:命名空间包含定义区域性相关信息的类,这些信息包括语言、国家/地区、使用的日历、日期、货币和数字的格式模式
以及字符串的排序顺序。我们可以使用这些类编写全球化(国际化)应用程序。
CurltureInfo:表示有关特定区域性的信息,包括区域性的名称、书写体系和使用的日历,以及有关对常用操作(如格式化日期和排序字符串)提供信息的区域性特定对象的访问
3. Path.Combine
命名空间:System.IO; 用法:public static string Combine(string path1, string path2),返回值为合并的路径的字符串。
4. HttpRuntime.AppDomainAppPath
获取目前应用程序定义域里装载(Host)应用程序的目录的实体磁盘路径。
5. DirectoryInfo
命名空间:System.IO; 公开用于创建、移动和枚举目录和子目录的实例方法,无法继承此类。
DirectoryInfo.GetFiles
返回当前目录的文件列表。语法:public FileInfo[] GetFiles(); 返回FileInfo[],FileInfo类型数组。返回文件的名称顺序无法保证;如果需要特定排序顺序,请使用Sort()方法。
Directory.GetFiles(String,String,SearchOption)
返回指定目录中文件的名称,该目录与指定搜索模式匹配并使用某个值确定是否在子目录中搜索。
http://skybirdzw.blog.163.com/blog/static/7257062620099751329403/
6. FileInfo
命名空间:System.IO; 提供创建、复制、删除、移动和打开文件的实例方法,并且帮助创建FileStream对象,无法继承此类。
7. Path.GetFileNameWithoutExtension
返回不具有扩展名的指定路径字符串的文件名。 此方法不验证路径或文件名是否存在。
8. LastIndexOf,Substring(暂不研究,留待以后)