首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >表格的自动翻译

表格的自动翻译
EN

Code Review用户
提问于 2011-02-10 11:12:42
回答 2查看 4.6K关注 0票数 8

我希望我的应用程序支持多种UI语言(又名i18n)。为此,我在下面构建了静态类,以便自动将表单及其所有内容转换为所需的语言。它查看用户的区域性的资源文件,并将控件的.Text属性替换为它在那里找到的字符串,或者返回到初始字符串,即英语。

用法是从每个表单的构造函数调用TranslateForm(this)。

关于我的代码有两个关注点:

*“翻译”方法超载。我没有找到任何办法来克服这一切。

*特别处理不同的管制措施,这似乎是不必要的。

我不是一个专业的程序员,所以任何纠正/增强/修复我的代码都是非常受欢迎的!

代码语言:javascript
运行
复制
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Globalization;
using System.Resources;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;

namespace blahblah
{
    static class TranslationHelper
    {
        static private ResourceManager rm = null;

        static private CultureInfo default_ci = null;

        static private CultureInfo lang_ci = null;

        /// <summary>
        /// translate control into the specific lang, or leave it untranslated if no translation string found
        /// </summary>
        /// <param name="ctrl"></param>
        /// <param name="lang"></param>
        static private void Translate(Control ctrl, string lang)
        {
            string str = TranslateString(ctrl.Name, lang);
            if (str != null)
                ctrl.Text = str;
        }

        static private void Translate(ToolStripMenuItem o, string lang)
        {
            string str = TranslateString(o.Name, lang);
            if (str != null)
                o.Text = str;
        }

        static private void Translate(ToolStripItem o, string lang)
        {
            string str = TranslateString(o.Name, lang);
            if (str != null)
                o.Text = str;
        }

        static private void Translate(Form o, string lang)
        {
            string str = TranslateString(o.Name, lang);
            if (str != null)
                o.Text = str;
        }

        /// <summary>
        /// returns the <c>name</c> string from the <c>lang</c> resource
        /// </summary>
        /// <param name="name">string/key name</param>
        /// <param name="lang">the language to translate to</param>
        /// <returns>a translated string for <c>name</c></returns>
        static public string TranslateString(string name, string lang)
        {
            if (lang_ci == null || !lang_ci.TwoLetterISOLanguageName.Equals(lang))
                lang_ci = new CultureInfo(lang);

            try
            {
                return rm.GetString(name, lang_ci);
            }
            catch (Exception)
            {
                // no translation yet
                try
                {
                    return rm.GetString(name, default_ci);
                }
                catch (Exception)
                {
                    return null;
                    //MessageBox.Show(ex.Message.ToString(), name);
                    //System.Console.WriteLine(ex.Message.ToString());
                }
            }
        }

        static public void TranslateForm(string lang, Form parent)
        {
            if (rm == null)
                rm = new ResourceManager("etimet.i18nResources.i18n", Assembly.GetExecutingAssembly(), null);
            if (default_ci == null)
                default_ci = new CultureInfo("en");

            // handle direction
            if (Program.conf.CurrentLang.Equals("he") || Program.conf.CurrentLang.Equals("ar") || Program.conf.CurrentLang.Equals("fa"))
            {
                parent.RightToLeft = RightToLeft.Yes;
            }
            else
            {
                parent.RightToLeft = RightToLeft.No;
            }

            // translate the form itself
            Translate(parent, lang);

            // translate all the children controls, recursively
            Control.ControlCollection c = parent.Controls;
            foreach (Control o in c)
            {
                // special handling for the menu
                if (o.GetType() == typeof(MenuStrip))
                {
                    foreach (ToolStripMenuItem it in ((MenuStrip)o).Items)
                    {
                        Translate(it, lang);
                        //MessageBox.Show(it.Text);
                        foreach (ToolStripItem f in it.DropDownItems)
                        {
                            if (typeof(ToolStripSeparator) != f.GetType())
                                Translate(f, lang);
                        }
                    }
                }
                RecursiveTranslateCtrl(lang, o);
            }
        }

        static private void RecursiveTranslateCtrl(string lang, Control ctrl)
        {
            Translate(ctrl, lang);

            foreach (Control c in ctrl.Controls)
            {
                RecursiveTranslateCtrl(lang, c);
            }
        }
    }
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2011-02-11 14:40:18

有内置的机制可以自动切换整个表单以使用区域性特定资源文件中的文本,而且它比仅仅设置text属性(例如ToolTips)更强大。您需要手动从资源文件加载的唯一时间是消息框之类的东西,但是除非您需要在显示警报的同时阻止应用程序,否则最好使用同样可本地化的气球提示。是一个容易开始的地方。它也将更有效,因为控件本身是本地化的,因此不需要遍历任何东西。

票数 5
EN

Code Review用户

发布于 2011-02-10 19:51:43

您可以通过在ToolStripItem上使用公共超类来避免重载:

代码语言:javascript
运行
复制
static private void Translate(ToolStripItem o, string lang)
{
   string str = TranslateString(o.Name, lang);
   if (str != null)
      c.Text = str;
}

不幸的是,这只适用于这两种组件类型,因为它看起来像Component没有NameText属性。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档