.NET 1.1 WinForm UI 多國語系做法

.NET 1.1 WinForm UI 多國語系做法

前言

在.NET 1.1使用VS2003開發Winform程式,並無法像VS2008可以依不同語系設定不同的UI Layout! 加上一堆程式已寫好,而且用了一些Third Party的元件,無法正常升到.NET 2.0,所以只好自己來處理!

image

實作

中文UI如下,

image

英文UI如下,

image

想到的方式如下,

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,22

2.修改.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檔之中就可以了!

 

 

測試範例

WinFormUI.rar

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^