2019年11月14日 星期四

[C#] Visual Studio 2019 Form多語言(在地化)設定

在App開發上常遇到UI介面上顯示多語言的需求,先前沒碰過C#,
現在工作上正好有所涉入研究出一些小心得,
一方面怕時間一久會忘記,所以上來備份一下,順便梳理自己的思緒,
歡迎各位批評指教,如果有錯誤再麻煩告知,謝謝。


開啟Form後,進入屬性,將Localizable改為ture,
之後可在Language裡選擇你要新增的語言。
在任何原件上更改過Text屬性後,會在方案總管中的Form1.cs中,
自動新增語言的resx檔。
如果要修改resx檔的內容除了直接點選進去修改外,
還可以改變Language的值後,UI介面會自動改至該語言,
然後直接修改UI上的文字即可。
PS.圖中的Form1.resx是指Language中的(預設),
如果找不到對應的語言會直接套用這resx的值,
也就是說你有新增跟你系統相同的語言的話,程式開啟會直接套用你新增的resx的值。
如果你要開啟時指定resx檔,要在Program.cs中增加
Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("zh-TW");
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("zh-TW");
如果要預設的resx則改為
Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("");
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("");
PS.一定要在Application.Run(new Form1()); 之前加入。
主要是因為在InitializeComponent()中會引用resx內的值。
所以主要的程式碼是
//載入ResourceManager
System.ComponentModel.ComponentResourceManager resources =
new System.ComponentModel.ComponentResourceManager(typeof(Form1));

//新增一個物件
this.button1 = new System.Windows.Forms.Button();

//套用對應的resx值(參數1:套用的物件,參數2:resx中的key值)
resources.ApplyResources(this.button1, "button1");

但以上方法只有針對UI介面的語言,如果有其他字串需要隨著更改語言
(如:MessageBox的內容)則不適用,必須使用另一個方法。

先在專案中,右鍵=>加入=>新增項目。
選取『資源檔』。
在方案總管中會產生剛剛的resx檔。
點開後可編輯key/value。
命名規則與Form1內的resx相同(檔名.語系.resx => Resource1.zh-TW.resx)
PS.Language(預設)會讀取Resource1.resx
載入的方式很簡單(資源檔名稱.Key值 => 回傳value)
PS.注意所有的resx檔都必須要有對應相同的key值,
只要改變Culture,系統會自動載入相對應的value。

為了方便管理resx檔,Visual Studio有延伸的模組可以使用。
在延伸模組 => 管理延伸模組 => 線上 => 搜尋『ResXManager』。
安裝完後會重新啟動Visual Studio,然後在工具中會出現ResXManager。
在最左邊可以選取resx檔所屬的檔名。
選取後,右邊會出現相對應的key以及相關語言的value。
以上就是基本的在地化(多語言)的相關設定。



以下是比較進階的用法及需要注意的事項。

進階用法:
如果需要記錄當前使用的語言在下一次開啟時使用相同的語言,
就要將值存入Properties.settings之中。

首先在方案總管中找到Settings.settings。
然後選開Settings.settings可以編輯key/value,以及value的類型。
載入的方式。
存儲的方式。
再配合先前的方法就能組合出重新啟動程式時自動載入先前選擇的語言。

注意事項:
如果你有使用Timer並且在Timer中使用到resx內的資源時,
若在Timer.Start();期間有改變Culture。
例如:
你設定一個Button按下去後改變語言。
Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("zh-TW");
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("zh-TW");
改變為
Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("");
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("");

此時Timer內的Resource會指向到zh-TW,而不是你想要的(預設)。
因為Timer是另一個Thread不是Thread.CurrentThread(主執行緒),
所以要將Timer停止後再重新啟動一次。

原本:
修改為

沒有留言:

張貼留言