[Silverlight] 在 Silverlight 2.0 中開發多語系的應用程式時的注意事項

Silverlight 2.0 可以發展多語系的應用程式,只要透過資源檔即可做到 Localization 的能力,但是...它卻有一個討厭的缺陷,想知道是何種缺陷,就點進來看吧。

在 Silverlight 2.0 中發展多語系應用程式,其實就像在 Windows Forms,或像在 ASP.NET Web Form 那樣容易,只要新增對應語系的資源檔,即可做到即時套用多語系介面的能力,例如若要在 Silverlight 發展多國語系介面,你的專案可能會看起來像這樣:

Silverlight Project
 -- Resources (資料夾)
    -- StringTable.resx (預設語系,例如繁體中文)
    -- StringTable.en-us.resx (英文)
    -- StringTable.fr.resx (法文)
    -- StringTable.zh-cn.resx (簡體中文)

然後依照 key-value 的方式去定義各語系的字串,即可完成語系文字部份的定義,然後,在 XAML 中導入資源檔,例如(下面的範例省略了一些內容,但省略的都是新增時就會有的):

<UserControl xmlns:Res="clr-namespace:MyProject.Resources">
    <UserControl.Resources>
        <Res:StringTable x:Name="StringTable"></Res:StringTable>
    </UserControl.Resources>
    <Grid>
        <TextBlock Text="{Binding MyString, Source={StaticResource, StringTable}}" />   
    </Grid>
</UserControl>

即可顯示預設的語系字串中,以 MyString 為名稱的字串內容,若要顯示英文語系,則在程式中變更 Thread.CurrentThread.CurrentCulture 屬性值即可,例如:

using System.Globalization;

Thread.CurrentThread.CurrentUICulture = new Culture("en-us");
Thread.CurrentThread.CurrentCulture = new Culture("en-us");

若要在程式中讀資源字串,則可以用這個方法:

using System.Resources;
using System.Reflection;

ResourceManager rm = new ResourceManager("AverMediaFtpManagerUICtls.Resources.StringLibrary", Assembly.GetExecutingAssembly());
string result = rm.GetString(ResourceID);
rm = null;
return result;

一切看起來是多麼的美好,但是如果你修改到預設資源語系的字串檔,只要有新增 key 或刪除 key 的話,Silverlight Tools 會自動覆寫資源檔後置的程式碼檔案,這在 Windows Forms 其實沒有問題的,但在 Silverlight 中卻會造成無法載入資源的錯誤狀況(即字串都消失了)

原因出在 StringTable.Designer.cs 這個檔案中(看你的資源檔怎麼命名的),把它打開來看會看到類似下列的程式碼:

public class StringTable
{
     ...

     internal StringTable() // 這段就是問題所在
     {
           ....
     }

     ....
}

 

由於 StringTable 的建構式被設定為 internal,而 Silverlight Tools 預設又將資源檔建成另一個 DLL (像是 \bin\zh-tw\MyProject.resources.dll),internal 的設定會讓主程式無法載入資源 DLL,解決方式是將 internal 改成 public 就可以了:

public class StringTable
{
     ...

     public StringTable() // 這樣就正常了
     {
           ....
     }

     ....
}

但讀者要切記的是,每次對資源檔中的字串做增刪時,這個程式宣告都會自動變回 internal,所以要記得將它改回來,否則在程式中所有套用資源的字串都會不見 ...

PS: 若讀者不知道如何做 Silverlight 2.0 的 Localization,可參考:
http://msdn.microsoft.com/zh-tw/library/cc838238(VS.95).aspx