ASP.NET开源框架之HIPPO技术内幕(四)--多语言的实现

四、多语言的实现

    上一章讲的是如何实现与数据的连接,本章来讲一下多语言是如何实现的。

    现在很多公司都已经开展了国际化的运作,所以多语言的支持已经成为必须要考虑的一个因素,现在能真正实现多语言的系统大多都比较昂贵。

    本系统的多语言支持直接得益于asp.net本身,它们本身都是使用UTF-8格式来存储,不是传统的本地编码。在asp.net页面中,每个控件都可以为多个国家字符集指定不同的字符串,但是这种方式不太灵活,特别是很多内容都是从数据库中拼凑出来的时候。为此我采用了另外一种方式,类似于资源文件,只是直接把内容写入了web.config中,这样以明文的形式来存储,并且web.config文件更改后,网站可以实现自动更新,不需要重新起动IIS。

    在web.config中,存储多语言的部分如下例:

        <add key="STRING_EN_内容管理" value="Content" />

        <add key="STRING_EN_系统管理" value="System" />

        <add key="STRING_EN_权限管理" value="Privilege" />

        <add key="STRING_RU_内容管理" value="содержание" />

        <add key="STRING_RU_系统管理" value="Система" />

        <add key="STRING_RU_权限管理" value="привилегированность" />

    可以看出,是直接对<appSettings>进行的扩展使用,没有建立新的段,key分成三部分:

        u STRING

        u EN / RU

        u 需要翻译的中文

    STRING用来标识,在后面的程序中会用到,而EN表示需要翻译成何种语言,如果您需要其它语种,只要在这里指定即可,如上例就是指定了英文和俄文两个语言,加上默认的中文,共有三种语言支持。最后只要把翻译的结果写在value这个属性里即可。

    在配置了这个文件后,看起来以后每写一个asp.net页面都需要写很多的程序去翻译里面的字符,其实不是这样的,我还定义了一个基类,继承自Page,命名为local,在这个页面的Page_Load函数中,自动搜索页面中所包括的各种控件,比如文本框,标签,按钮,甚至图片框等,然后根据当前指定的语言(可由Session中寻找,也可以由Post中查看),选择相对应的翻译,就实现了多语言。

    上面也提到了图片框,在多语言环境中,很多图片里都固化了本地的文字,所以对图片也需要替换。我在网站的images目录中,根据不同的语言增加了相应的子目录,如images/EN images/RU 等等,在翻译的时候,会把图片的路径由 images/a.gif 拼接成 images/EN/a.gif这种样式,就实现了图片的自动替换,当然前提是您已经准备了充足的图片用于替换。

    取得页面中的所有控件可以用下面的函数:

foreach(Control control in parent.Controls)

{

}

    在数据库中,有一个专门的表ZR_LANG来存储当前系统所支持的语言,在登录界面(包括前端和后端)都会从这里判断,多语言选择需要支持哪些语言。

    如果页面的标题写在asp.net的页面里,那么是不能利用上面的方式来翻译的,所以我专门做了一个Label,来存放标题的内容,然后在页面中按如下方式来引用标题:

<HTML> <HEAD> <title><%=lblTitle.Text%></title> ….

    这样在运行后,就可以实现正确的标题的翻译了。

    关于Grid表格,对于Caption的翻译,并不难做,但是需要根据不同的语言,对Grid中的实际内容进行翻译,这是比较难做的,我在这里用了一个小技巧来实现:把Grid中需要翻译内容的列的前面加一个空格,在实际工作中,遇到有空格的列,就表明其中的内容需要翻译,然后就一条条的翻译过来即可。为什么加一个空格呢,首先,它不会对显示有什么影响,另外,这样也可以区别对待,不需要翻译的列,就不需要使用此方式来占用过多的时间了。以下两个函数处理此事,请参考:

public static void LocalGrid(ref System.Web.UI.WebControls.DataGrid grid)

{

System.Web.UI.Page page = new System.Web.UI.Page();

if (page.Session["__LANGUAGE__"] != null)

{

if (page.Session["__LANGUAGE__"].ToString() == "TW" || page.Session["__LANGUAGE__"].ToString() == "EN")

{

string lang = page.Session["__LANGUAGE__"].ToString();

foreach( System.Web.UI.WebControls.DataGridColumn column in grid.Columns )

{

string text = column.HeaderText;

if (System.Configuration.ConfigurationSettings.AppSettings["STRING_" + lang + "_" + text] != null)

{

text = System.Configuration.ConfigurationSettings.AppSettings["STRING_" + lang + "_" + text];

}

else

{

if (lang == "TW")

{

text = Big5.GetBig5Code(text);

}

}

column.HeaderText = text;

}

}

}

}

/// <summary>

/// 本地化一个GRID里的内容

/// </summary>

/// <param name="grid">表格</param>

public static void LocalGridContent(ref System.Web.UI.WebControls.DataGrid grid)

{

System.Web.UI.Page page = new System.Web.UI.Page();

if (page.Session["__LANGUAGE__"] != null)

{

ArrayList cols = new ArrayList();

int i = 0;

foreach( System.Web.UI.WebControls.DataGridColumn column in grid.Columns )

{

string text = column.HeaderText;

if (text.Substring(0,1) == " ")

{

column.HeaderText = Tran(column.HeaderText);

cols.Add(i);

}

i++;

}

if (cols.Count > 0)

{

int cnt = grid.Items.Count;

for (int j = 0; j < cnt; j++)

{

foreach(object col in cols)

{

int colNumber = (int)col;

string content = grid.Items[j].Cells[colNumber].Text ;

content = Tran(content);

grid.Items[j].Cells[colNumber].Text = content;

}

}

}

}

}

    到此,已经基本讲了多语言的一些实现方式,在后面一节会来重点讲一下本系统的控件结构。

posted on 2010-04-17 12:29  Aicken(李鸣)  阅读(1772)  评论(0编辑  收藏  举报