1. 程式人生 > >C#的Winform多語言實現(API翻譯)

C#的Winform多語言實現(API翻譯)

       呼叫百度翻譯API實現Winform多語言切換,本博文提供的程式碼可以實現簡體中文、繁體中文、英文的切換。如果需要增加其它語言的切換,只需要呼叫API將其翻譯為想要的語言 即可。 並且,當修改了語言之後,會更新所有開啟的視窗

       呼叫API翻譯可以省去人工翻譯的麻煩,但是卻會帶來翻譯不準確的問題,而且會有一定的延遲,每次切換語言都需要 等待一段時間。因此,建議將API實現方式與XML實現方式或resx實現方式結合在一起使用。對於某些常用的語言,如英語,可以使用XML檔案或resx檔案實現切換;對於不常用的語言,使用API翻譯實現切換。XML和resx實現方式,在子豐 之前的博文中都有介紹。

先貼幾張圖展示一下效果。

http://download.csdn.net/detail/softimite_zifeng/9731576

1. 簡體中文


2. 繁體中文


3. 英文


下面子豐介紹一下實現的過程:

1. 到百度翻譯API的官網申請appid和金鑰,只要你有郵箱和手機號就能申請到。

注:子豐給出的程式中的appid和金鑰都是隨便寫的,因此,程式下載之後必須要將這兩項修改為你申請到的appid和金鑰。

百度翻譯開放平臺:點選開啟連結

2. 在專案的Properties的Settings.settings中新增變數DefaultLanguage,用於儲存當前設定的預設語言。當下次啟動程式時,會讀取該變數,從而將程式的語言設定為上次程式關閉時的語言。



3. 建立一個靜態類(MultiLanguage.cs)用於編寫與切換語言相關的變數和程式碼。

(1)變數DefaultLanguage,用於儲存當前預設語言

//當前預設語言
public static string DefaultLanguage = "zh";
(2)函式SetDefaultLanguage修改當前預設語言
/// <summary>
/// 修改預設語言
/// </summary>
/// <param name="lang">待設定預設語言</param>
public static void SetDefaultLanguage(string lang)
{
    DefaultLanguage = lang;
    Properties.Settings.Default.DefaultLanguage = lang;
    Properties.Settings.Default.Save();
}
(3)建立類用於儲存從百度翻譯API獲取到的結果
public class Translation
{
    public string Src { get; set; }
    public string Dst { get; set; }
}

public class TranslationResult
{
    public string Error_code { get; set; }
    public string Error_msg { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public string Query { get; set; }
    public Translation[] Trans_result { get; set; }
}
(4)函式GetTranslationFromBaiduFanyi呼叫百度翻譯API將源語言翻譯為目標語言
/// <summary>
/// 呼叫百度翻譯API進行翻譯
/// 詳情可參考http://api.fanyi.baidu.com/api/trans/product/apidoc
/// </summary>
/// <param name="q">待翻譯字元</param>
/// <param name="from">源語言</param>
/// <param name="to">目標語言</param>
/// <returns>翻譯結果</returns>
private static string GetTranslationFromBaiduFanyi(string q, string from, string to)
{
    //可以直接到百度翻譯API的官網申請
    //此處的都是子豐隨便寫的,所以肯定是不能用的
    //一定要去申請,不然程式的更改語言功能不能使用
    string appId = "0123456789";
    string password = "0123456789";

    string jsonResult = String.Empty;
    string languageFrom = from.ToLower();
    string languageTo = to.ToLower();
    string randomNum = System.DateTime.Now.Millisecond.ToString();
    string md5Sign = GetMD5WithString(appId + q + randomNum + password);
    String url = String.Format("http://api.fanyi.baidu.com/api/trans/vip/translate?q={0}&from={1}&to={2}&appid={3}&salt={4}&sign={5}", HttpUtility.UrlEncode(q, Encoding.UTF8), languageFrom, languageTo, appId, randomNum, md5Sign
        );
    WebClient wc = new WebClient();
    try
    {
        jsonResult = wc.DownloadString(url);
    }
    catch
    {
        jsonResult = string.Empty;
    }
    JavaScriptSerializer jss = new JavaScriptSerializer();
    TranslationResult ret = jss.Deserialize<TranslationResult>(jsonResult);
    if (ret.Error_code == null)
    {
        return ret.Trans_result[0].Dst.Trim();
    }
    else
    {
        //翻譯失敗,返回原來的字元
        return q;
    }
}

/// <summary>
/// md5加密
/// </summary>
/// <param name="input">待加密字串</param>
/// <returns>加密結果</returns>
private static string GetMD5WithString(string input)
{
    //input必須轉換為UTF-8編碼
    if (input == null)
    {
        return null;
    }
    MD5 md5Hash = MD5.Create();
    // 將輸入字串轉換為位元組陣列並計算雜湊資料  
    byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
    // 建立一個 Stringbuilder 來收集位元組並建立字串  
    StringBuilder sBuilder = new StringBuilder();
    // 迴圈遍歷雜湊資料的每一個位元組並格式化為十六進位制字串  
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString("x2"));
    }
    // 返回十六進位制字串  
    return sBuilder.ToString();
}
(5)函式LoadLanguage用於載入語言或切換語言
/// <summary>
/// 載入語言
/// </summary>
/// <param name="form">載入語言的視窗</param>
public static void LoadLanguage(Form form)
{
    //獲取當前視窗的所有控制元件
    Control.ControlCollection sonControls = form.Controls;
    try
    {
        //遍歷所有控制元件
        foreach (Control control in sonControls)
        {
            if (control.GetType() == typeof(Panel))     //Panel
            {
                GetSetSubControls(control.Controls);
            }
            else if (control.GetType() == typeof(GroupBox))     //GroupBox
            {
                GetSetSubControls(control.Controls);
            }
            else if (control.GetType() == typeof(TabControl))       //TabControl
            {
                GetSetSubControls(control.Controls);
            }
            else if (control.GetType() == typeof(TabPage))      //TabPage
            {
                GetSetSubControls(control.Controls);
            }
            if (control.Tag != null)
            {
                if (control.Tag.ToString().Trim() != "")
                {
                    //呼叫百度翻譯API
                    control.Text = GetTranslationFromBaiduFanyi(control.Tag.ToString().Trim(), "zh", DefaultLanguage);
                }
            }
        }
        if (form.Tag != null)
        {
            if (form.Tag.ToString().Trim() != "")
            {
                //呼叫百度翻譯API
                form.Text = GetTranslationFromBaiduFanyi(form.Tag.ToString().Trim(), "zh", DefaultLanguage);
            }
        }
    }
    catch { }
}

/// <summary>
/// 獲取並設定控制元件中的子控制元件
/// </summary>
/// <param name="controls">父控制元件</param>
private static void GetSetSubControls(Control.ControlCollection controls)
{
    try
    {
        foreach (Control control in controls)
        {
            if (control.GetType() == typeof(Panel))     //Panel
            {
                GetSetSubControls(control.Controls);
            }
            else if (control.GetType() == typeof(GroupBox))     //GroupBox
            {
                GetSetSubControls(control.Controls);
            }
            else if (control.GetType() == typeof(TabControl))       //TabControl
            {
                GetSetSubControls(control.Controls);
            }
            else if (control.GetType() == typeof(TabPage))      //TabPage
            {
                GetSetSubControls(control.Controls);
            }
            if (control.Tag != null)
            {
                if (control.Tag.ToString().Trim() != "")
                {
                    //呼叫百度翻譯API
                    control.Text = GetTranslationFromBaiduFanyi(control.Tag.ToString().Trim(), "zh", DefaultLanguage);
                }
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
}

4. 在主視窗的Load事件中讀取Properties.Settings.Default.DefaultLanguage,並將ComboBox賦值為當前預設語言,即簡體中文、繁體中文或英文。

private void LoginForm_Load(object sender, EventArgs e)
{
    //設定combobox的值
    string language = Properties.Settings.Default.DefaultLanguage;
    if (language == "zh")
    {
        languageTxt.Text = "簡體中文(預設)";
    }
    else if (language == "cht")
    {
        languageTxt.Text = "繁體中文";
    }
    else if (language == "en")
    {
        languageTxt.Text = "English";
    }
}

5. 在每個視窗的Load事件中呼叫函式MultiLanguage.LoadLanguage,使視窗在出現時即顯示為當前預設語言。

private void PasswordForm_Load(object sender, EventArgs e)
{
    //載入語言
    MultiLanguage.LoadLanguage(this);
}

6. 編寫用於切換語言的ComboBox的SelectedIndexChanged事件,使得當使用者選擇對應的語言時,程式會切換到該語言。
private void languageTxt_SelectedIndexChanged(object sender, EventArgs e)
{
    languageTxt.Enabled = false;
    if (languageTxt.Text == "簡體中文(預設)")
    {
        //修改預設語言
        MultiLanguage.SetDefaultLanguage("zh");
        //對所有開啟的視窗重新載入語言
        foreach (Form form in Application.OpenForms)
        {
            MultiLanguage.LoadLanguage(form);
        }
    }
    else if (languageTxt.Text == "繁體中文")
    {
        //修改預設語言
        MultiLanguage.SetDefaultLanguage("cht");
        //對所有開啟的視窗重新載入語言
        foreach (Form form in Application.OpenForms)
        {
            MultiLanguage.LoadLanguage(form);
        }
    }
    else if (languageTxt.Text == "English")
    {
        //修改預設語言
        MultiLanguage.SetDefaultLanguage("en");
        //對所有開啟的視窗重新載入語言
        foreach (Form form in Application.OpenForms)
        {
            MultiLanguage.LoadLanguage(form);
        }
    }
    languageTxt.Enabled = true;
}