本地化而无需重新编译项目

时间:2013-07-31 11:48:44

标签: c# xml winforms localization

我正在构建一个项目,我需要使它非常可定制。我正在尝试构建它以支持4种语言。并且用户将具有管理面板,他/她可以在其中更改标签的文本或按钮的文本。我希望用户转到该管理面板并更改按钮的文本,而不是给我打电话:)

我使用了旧的但很好的本地化风格,即.resx文件。我在下面有示例代码。

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {

        if (comboBox1.SelectedItem.ToString().Equals("en-GB"))
        {
            Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-GB");
            label1.Text= FormLabels.test1;
            label2.Text = FormLabels.test2;
        }
        else if (comboBox1.SelectedItem.ToString().Equals("de-DE"))
        {
            Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE");
            label1.Text = FormLabels.test1;
            label2.Text = FormLabels.test2;
        }
     }

如果我让用户更改“FormLabels.en-GB.resx”文件中的按钮文字。必须重新编译项目以查看更改。

我需要找到一个解决方案,用户可以通过重新编译来更改按钮的文本。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

我唯一能想到的就是在外部文件中进行本地化。 创建一个xml文件,如:

ex:languagesSupported.xml

    <Languages>
        <language name="English" file="en.dat" />
        <language name="French" file="fr.dat" />
        <language name="Japanese" file="jp.dat" />
    </Languages>

像这样你以后可以实际添加更多语言。

现在,在每个文件中,您需要执行以下操作:

(例如:en.dat)

    <Language name="English">
        <Localized name="hello" value="Hello">
        <Localized name="goodbye" value="Goodbye">
    </Language>

(例如:fr.dat)

    <Language name="French">
        <Localized name="hello" value="Bonjour">
        <Localized name="goodbye" value="Au revoir">
    </Language>

在您的代码中,您可以执行以下操作:

    private Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();

    private string _currentLocalization = "English";

    private bool LoadLocalizations()
    {
        try
        {
            if (File.Exists("languagesSupported.xml") == false)
            {
                return false;
            }

            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load("languagesSupported.xml");
            XmlNodeList nodeList = xmldoc.SelectNodes("languages/language");

            if (nodeList.Count > 0)
            {
                foreach (XmlNode node in nodeList)
                {
                    LoadLocalization(node.Attributes["name"].Value, node.Attributes["file"].Value);
                }
            }

            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }

    private bool LoadLocalization(string pLang, string pFile)
    {
        try
        {
            if (File.Exists(pFile) == false)
            {
                return false;
            }

            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(pFile);
            XmlNodeList nodeList = xmldoc.SelectNodes("language/localized");

            _localizations.Add(pLang, new Dictionary<string,string>());

            if (nodeList.Count > 0)
            {
                foreach (XmlNode node in nodeList)
                {
                    _localizations[pLang].Add(node.Attributes["name"].Value, node.Attributes["value"].Value);
                }
            }

            return true;
        }
        catch (Exception ex)
        {
            return false;
        }
    }

    private void SetLocalization()
    {
        labelHello.text = _localizations[_currentLocalization]["hello"];
        labelGoodbye.text = _localizations[_currentLocalization]["goodbye"];
    }

之后,每次用户更改语言时,只需更新_currentLocalization并调用SetLocalization();

您甚至可以使用_localizations中的键填充语言下拉列表。

通过这种方式,您可以使本地化完全动态化。

如果您真的想使用CultureInfo,只需将文化映射到语言名称。

答案 1 :(得分:0)

ResourceManager仅适用于嵌入资源。 您必须自己编写ResourceManager。

您可以使用ResXResouceSet(http://msdn.microsoft.com/en-us/library/system.resources.resxresourceset.aspx),然后围绕它编写自己的ResourceManager。 这并不难。 然后,您可以自己阅读resx文件并在resx扩展名之前添加文化。

祝你好运