.NET 1.1 WinForm UI 多國語系做法
前言
在.NET 1.1使用VS2003開發Winform程式,並無法像VS2008可以依不同語系設定不同的UI Layout! 加上一堆程式已寫好,而且用了一些Third Party的元件,無法正常升到.NET 2.0,所以只好自己來處理!
實作
中文UI如下,
英文UI如下,
想到的方式如下,
1.先將目前中文Form上面的所有物件Text, Location及Size,存到.zh-TW.ini檔之中(存取ini檔方式,請參考INI Files Will Never Die: How-To in .NET),在取屬性時,要注意的是,如果是UserControl的話,要加上Prefix,以免物件的Name相衝到哦!。
''' <summary> ''' 將Form上的Control寫到ini之中 ''' </summary> ''' ----------------------------------------------------------------------------- Public Sub WriteControlInfo2Ini() Dim strFilePath As String = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Path.GetFileNameWithoutExtension(Application.ExecutablePath) & "." & Me.cboLanguage.Text & ".ini") If File.Exists(strFilePath) = False Then '不存在,先建立空檔 Dim fs As FileStream = File.Create(strFilePath) fs.Close() End If '將Form上的物件都寫到ini之中 Dim fIniFile As New IniFile(strFilePath) fIniFile.WriteString(Me.Name, Me.Name & "_Size_WH", Me.Size.Width & "," & Me.Size.Height) WriteControlInfo2Ini(fIniFile, Me.Controls, Me.Name, String.Empty) End Sub
''' <summary> ''' 將物件資訊寫到Ini之中 ''' </summary> ''' ----------------------------------------------------------------------------- Private Sub WriteControlInfo2Ini(ByRef finiFile As IniFile, ByVal oControls As Control.ControlCollection, ByVal iniSessionName As String, ByVal prefixName As String) Dim strPrefix As String = prefixName If strPrefix.Length > 0 Then strPrefix &= "_" End If For Each MyCtl As Control In oControls Dim myPrefixName As String = strPrefix finiFile.WriteString(iniSessionName, strPrefix & MyCtl.Name & "_Location_XY", MyCtl.Location.X & "," & MyCtl.Location.Y) finiFile.WriteString(iniSessionName, strPrefix & MyCtl.Name & "_Size_WH", MyCtl.Size.Width & "," & MyCtl.Size.Height) finiFile.WriteString(iniSessionName, strPrefix & MyCtl.Name & "_Text", MyCtl.Text) If MyCtl.Controls.Count > 0 Then If TypeOf (MyCtl) Is UserControl Then myPrefixName &= MyCtl.Name & "_" End If WriteControlInfo2Ini(finiFile, MyCtl.Controls, iniSessionName, myPrefixName) End If Next End Sub
ini檔的內容如下,
[Form1]
Form1_Size_WH=656,500
UserControl21__UserControl11__Label2_Size_WH=112,23
UserControl21__UserControl11__Label2_Text=英文 UserCtrl Label2
UserControl21__UserControl11__Label1_Location_XY=8,16
UserControl21__UserControl11__Label1_Size_WH=112,23
UserControl21__UserControl11__Label1_Text=英文 UserCtrl Label1
UserControl21__UserControl11__TextBox2_Location_XY=8,96
UserControl21__UserControl11__TextBox2_Size_WH=100,222.修改.zh-TW.ini成英文合適的UI設定。
3.在程式再依語系切換設定各物件的Text, Location及Size。
''' <summary> ''' 依語系讀取設定值 ''' </summary> ''' ----------------------------------------------------------------------------- Public Sub ReadIniSetting() Dim strFilePath As String = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), Path.GetFileNameWithoutExtension(Application.ExecutablePath) & "." & Me.cboLanguage.Text & ".ini") If File.Exists(strFilePath) = False Then '不存在 'MsgBox("file not found:" & strFilePath) Exit Sub End If '依ini中的資料設定 Dim fIniFile As New IniFile(strFilePath) Dim ctlSize As String = fIniFile.GetString(Me.Name, Me.Name & "_Size_WH", String.Empty) AssignCtrlSize(Me, ctlSize) SetControlInfoFromIni(fIniFile, Me.Controls, Me.Name, String.Empty) End Sub ''' ----------------------------------------------------------------------------- ''' <summary> ''' 設定物件的屬性值 ''' </summary> ''' ----------------------------------------------------------------------------- Private Sub SetControlInfoFromIni(ByRef finiFile As IniFile, ByVal oControls As Control.ControlCollection, ByVal iniSessionName As String, ByVal prefixName As String) Dim strPrefix As String = prefixName If strPrefix.Length > 0 Then strPrefix &= "_" End If For Each MyCtl As Control In oControls Dim myPrefixName As String = strPrefix AssignCtrlSize(MyCtl, finiFile.GetString(iniSessionName, strPrefix & MyCtl.Name & "_Size_WH", String.Empty)) AssignCtrlLocation(MyCtl, finiFile.GetString(iniSessionName, strPrefix & MyCtl.Name & "_Location_XY", String.Empty)) Dim ctlText As String = finiFile.GetString(iniSessionName, strPrefix & MyCtl.Name & "_Text", String.Empty) If IsNothing(ctlText) = False AndAlso ctlText.Length > 0 Then MyCtl.Text = ctlText End If If MyCtl.Controls.Count > 0 Then If TypeOf (MyCtl) Is UserControl Then myPrefixName &= MyCtl.Name & "_" End If SetControlInfoFromIni(finiFile, MyCtl.Controls, iniSessionName, myPrefixName) End If Next End Sub ''' ----------------------------------------------------------------------------- ''' <summary> ''' 指定物件的Size大小 ''' </summary> ''' ----------------------------------------------------------------------------- Private Sub AssignCtrlSize(ByRef rCtrl As Control, ByVal vstrSize As String) If vstrSize Is Nothing = False AndAlso vstrSize.Length > 0 Then Dim arySize() As String = vstrSize.Split(",") If arySize.Length = 2 Then rCtrl.Width = arySize(0) rCtrl.Height = arySize(1) End If End If End Sub ''' ----------------------------------------------------------------------------- ''' <summary> ''' 指定物件的位置 ''' </summary> ''' ----------------------------------------------------------------------------- Private Sub AssignCtrlLocation(ByRef rCtrl As Control, ByVal vstrPoint As String) If vstrPoint Is Nothing = False AndAlso vstrPoint.Length > 0 Then Dim aryPoint() As String = vstrPoint.Split(",") If aryPoint.Length = 2 Then rCtrl.Location = New Point(aryPoint(0), aryPoint(1)) End If End If End Sub
結論
在上面的第2點,直接調整ini的Size及Location會比較辛苦! 也可以依zh-TW.ini建立出中、英文的對照表,然後Replace各程式中的中文字,然後再用VS2003開起來調整。等調整好了之後,再存到en-US.ini檔之中就可以了!
測試範例
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^