Hello world.

    在微软的VS2005/VS2008开发环境中对资源文件的支持已经达到了非常智能化的一个程度。所谓“资源文件”,其本质还是一个XML的文件,不过微软已经通过一定程度的封装,使得它操作起来非常容易便捷。同时,资源文件使用的最大好处在于它可以将文件、视频等内容混合编译(所以称为“内嵌资源”(Assembly Resource),随软件同步出售,避免了因为用户误操作(比如删除某个图片、文件)造成软件工作失常的问题。 

微软的资源文件可以分成两个类型——一个是全局资源文件,另一个是局部资源文件。

一、全局资源文件(Global Resource File):

全局资源文件(Global Resource File)是专门存放在APP_GlobalResources下的一种xml格式的文件。该文件往往被用作模板页、共享控件等页面使用,作为一种全局的资源在这个网站项目中被共享。

下面我们来看一个非常简单的资源文件的使用:

l 首先您可以打开一个工程,创建一个“App_GlobalResources”的文件夹,再创建一个后缀为“resx”的文件夹,此时您在后台代码中写入“Resource.”的时候,所有位于此文件夹下的资源文件被强制编译成了一个类,因而您可以直接获取这些数据,通常写法是这样的:

Resource.XXX.Name

 其中,XXX是全局资源文件的一个名称,您可以任意指定Name是其中的某个Key(假如您有一个Language.resx,其中有一个字符串的资源,Name为:ShowText,值为:This is a simple string. 那么你使用Resource.Language.ShowText即可得出结果。

 

l 当然,您也可以使用这样的代码进行访问:

base.GetGlobalResourceObject(资源文件名,Name=>弱类型,返回object,需要显示强制转换。

如上面的例子可以写成:

base.GetGlobalResourceObject("Language","ShowText").ToString();

 

l 有时你需要在HTML,ASPX等代码中混合中直接进行绑定,这样的话你可以直接使用如下的形式:

<前缀名:控件名 …… 属性='<%$Resources:资源文件名,Name%>'/>

如将上面文字绑定到一个TextBox中并且显示出来,您不妨可以这样做:

<asp:TextBox .... Text=<%$ Resources: Language, ShowText%>”/>

一般地,资源文件广泛地被用于“多国语言”自动翻译网站(比如一个中国客户登陆看到简体中文,一个英国人在英国应该看到英语等)。因此我们的全局语言资源文件常见的定义是“XXXX.语言-[区域].resx

实际上全局资源不一定用于单纯的语言切换。如果您想了解关于“语言-[区域]”的详细信息,请到IE中的“选项-->语言”,点击“添加”可以看到全部的语言简写(英文)。当然您可以使用编程的方法获得,代码如下:

 foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))

                {

                    Response.Write(ci.Name+"<br/>");

                }

 二、局部资源文件(Local Resource File):

      有时,资源不一定是被所有(或者大部分)网页共享,而是被局部的某个(些)所需。此时显然“全局资源”失效,您不得不采取“局部资源文件”。访问局部资源文件可以和全局一样,不过没有那么容易(没有强类型),一般可以采取这样的方式:

base.GetLocalResourceKey(Name) =>弱类型,需要显示强制转换

或者您还可以数据绑定,就像以下代码(情况同上):

<TextBox Id=XXXX” Text=<%$ Resources: ShowText%>/>

 

我们发现,和全局相比,您不必指定到底是那个资源文件?是对,因为微软足够聪明——它有一个潜规则:本地(当局)资源文件的命名必须和要使用该资源文件的网页的名称和扩展名完全一致(即一个AA.aspx要使用某个本地资源文件,那么资源文件必须命名成:AA.aspx.resx)。所以无论是手动编码,还是帮定编程,您都无需指定本地的资源文件名了。

局部资源文件还有一种特殊的绑定——多属性绑定,就是说如果有一个控件,你同时要绑定它的多个属性(比如TextBox绑定TextTooltip等,那么您的Name是这样的指定的:

TextBox.Tooltip

TextBox.Text

然后这样进行绑定:

<前缀:控件名…… Meta:ResourceKey="Name"/>

<asp:TextBox .... meta:ResourceKey = "TextBox"/>

系统会自动读取所有TextBox,然后分别反射属性,与当前被绑定的控件属性匹配进行自动绑定,这样您就不必一个个写不同的Name然后手动绑定了,神奇吧!

同样要说明:一个局部资源文件也不是仅仅用于语言切换,只是应用较多而已。它的定义通常以页面名.扩展名.语言-[区域].resx定义。

 

最后举一个例子——关于国际化(本地化)的应用(About Internationalization)

所谓“国际化”,就是说系统根据用户的浏览器默认第一语言设置,自动将语言转换成需要的那个对应语言,改变默认界面的文字表述方式,相当于一个简单的“语言翻译器”。为了实现这个目的,我们首先要接触一个类:

Thread.CurrentThread.CurrentUICulture:设置当前所处区域的语言。

该类的使用方法非常简单,您直接可以使用CultureInfo.CreateCulture(string name)进行手动选择。其中的name必须传入一个“语言-区域”的字符串。

               

 

下面给出具体的一个实际例子:

【例】现在假设我们要欢迎各国来宾到中国参加世博会,我们要做一个多国语言的世博网页,简单期间仅仅显示一行“欢迎来参加世博会!”的标语口号,要求适应本地化的需要(不同国家应当看到不同的语言)。

 

 

代码如下:

 


public partial class _Default : System.Web.UI.Page
    {
        static Dictionary<string, string> countries = new Dictionary<string, string>();

        protected override void InitializeCulture()
        {
            string language = Request.Form["ddlLanguage"];
            if (string.IsNullOrEmpty(language))
            {
                HttpCookie cl = Request.Cookies["language"];

                if (cl != null)
                {
                    Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cl.Value);
                }
            }
            else
            {
                HttpCookie cl = new HttpCookie("language", language);
                cl.Expires = DateTime.Now.AddMinutes(30);
                Response.Cookies.Add(cl);
                Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cl.Value);
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                countries = new Dictionary<string, string>();
                countries.Add(CultureInfo.CreateSpecificCulture("en-us").NativeName, "en-us");
                countries.Add(CultureInfo.CreateSpecificCulture("zh-cn").NativeName, "zh-cn");
                countries.Add(CultureInfo.CreateSpecificCulture("zh-tw").NativeName, "zh-tw");
                countries.Add(CultureInfo.CreateSpecificCulture("ja-jp").NativeName, "ja-jp");
                countries.Add(CultureInfo.CreateSpecificCulture("ru-ru").NativeName, "ru-ru");
                countries.Add(CultureInfo.CreateSpecificCulture("ko-kr").NativeName, "ko-kr");
                ddlLanguage.DataSource = countries;
                ddlLanguage.DataTextField = "Key";
                ddlLanguage.DataValueField = "Value";
                ddlLanguage.DataBind();

                //第一次加载时候自动和下拉框语言同步

                string language = Thread.CurrentThread.CurrentUICulture.Name;

                foreach (ListItem item in ddlLanguage.Items)
                {
                    if (item.Value == language.ToLower())
                    {
                        item.Selected = true;
                        break;
                    }
                }
            }
        }
    }

 

【重点说明】:

 

1、               要实现语言的改变,首先必须重写InitializeCulture方法,示例中首先将获取DropDownList的Value(因为这个语言选项框可以改变,从而发生Post),并且判断(如果Post的结果为null,则表明是第一次加载;然后再进一步判断是否用户设置过语言(从Cookie中读取),如果有则将当前线程的“语言-区域”设置成Cookie中的那个语言环境,没有则采取默认情况;如果Post的结果不为null,表明用户已经修改了该语言,把它存放到Cookie中,然后设置当前的语言选项。

2、               在page_load事件中除了必要的语言包选项加载之外,下拉框还实现了和当前语言同步显示的功能。其原理是将一次性生成Dictionary的Key和Value分别与下拉框进行绑定,然后循环对比。

3、               注意:Thread.CurrentThread.CurrentUICulture仅仅对当前页面有效,如果所有页面都要求设置成同一个语言,必须每个页面都写InitializeCulture方法(显然罗嗦),此时您可以采取两种方法:

I)               直接人为写一个类,继承Page并重写该方法,最后让所有的页面都直接继承你手动的那个类(还是有些手动)。

II)            创建Global.asax文件,然后将代码拷贝一下即可(推荐):

 


protected void Application_BeginRequest(object sender, EventArgs e)
        {
            string language = Request.Form["ddlLanguage"];
            if (string.IsNullOrEmpty(language))
            {
                HttpCookie cl = Request.Cookies["language"];

                if (cl != null)
                {
                    Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cl.Value);
                }
            }
            else
            {
                HttpCookie cl = new HttpCookie("language", language);
                cl.Expires = DateTime.Now.AddMinutes(30);
                Response.Cookies.Add(cl);
                Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cl.Value);
            }
        }

 from:http://www.cnblogs.com/serviceboy/archive/2009/07/11/1521472.html

 
posted on 2013-04-25 18:08  Ryan.zhu  阅读(355)  评论(0编辑  收藏  举报
come soon on