2009-05-02 18 views
19

WPFアプリケーションの多言語システムを実装するための良い方法をお勧めしますか?今私が使用しているメソッドには、XML、クラス、およびxaml拡張が含まれます。ほとんどの場合、うまく動作しますが、一般的に動的ラベルやダイナミックテキストに対処する必要があるときは、余分な努力が必要です。私はプログラマーに主要な問題でしか働かせずに、langの問題を忘れさせたいと思っています。WPFの多言語

答えて

17

私はWPF Localization Extensionを使用しています。 DependencyPropertyの任意のタイプをDependencyObjectにローカライズするのは本当に簡単な方法です。

  • の.resx、フォールバック機構付Text = {LocText ResAssembly:ResFile:ResKey}
  • 作品のような結合のような文体サポート
  • 実際の安定状態にある(例えばEN-USを - >アン - >独立した文化)
  • 文化強制をサポートするP)、追加の名前空間
  • せずに使用することができます:コントロールテンプレート
  • 作品は本当に(XAMLで使用することができ、通常の依存関係プロパティを持つ
  • 作品は)「これはすべての時間を英語にする必要があり」ローカライズされた値を動的に生成されたコントロールにバインドするコード。
  • は、先進的な使用のためにINotifyPropertyChangedを実装します。
  • サポートする文字列の書式"this is the '{0}' value"
  • ランタイムの言語の
  • 切り替えがNOタイムスライス
  • が可能影響(私の広報物など)の生産システムで使用されている
  • (現在LocText拡張子を持つ)の接頭辞と接尾辞の値をサポートしています
  • ( "特殊なローカライズ辞書を登録するためにxyzを呼び出す"のような)初期化プロセスは必要ありません。
  • すべてのアセンブリ間で任意のリソースファイル( .resx
  • は、設計時に利用可能である(MSのExpression Blendが、MSのVisual Studio 2008(ノーマルとSP1)選択した言語の
  • 変更は、設計時に可能である
  • は限り、データ型のいずれかのタイプをローカライズすることができます
  • Textのサポートが組み込まれていコンバータ(TypeConverter)が存在するため(LocalizeExtensionを拡張)、上部Text、下部TextImage S、Brush ES、DoubleThickness
  • 任意のメモリに影響を与えないが
  • をリーク
  • は、UIDのプロパティをそのままにします。
  • は、としてIFormatProvider(たとえば、私がしました。この記事を使用して(123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20"または"123,20"
  • の後ろにコード内でリソース値をチェックして、取得するためのいくつかの機能がThread.CurrentCultureまたはThread.CurrentUICultureに文化を変更しません提供しています(簡単に変更することができます)
+6

これを使用する方法に関するドキュメントやチュートリアルはありませんか? –

+1

文書が利用可能になりましたhttp://wpflocalizeextension.codeplex.com/documentation – SeriousM

32

は、次の手順に従います。

1)場所を別々のリソースファイル内のすべてのStringの断片。

例:StringResources.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:system="clr-namespace:System;assembly=mscorlib"> 

    <!-- String resource that can be localized --> 
    <system:String x:Key="All_Vehicles">All Vehicles</system:String> 

</ResourceDictionary> 

2)マージされた辞書に)翻訳(言語ごとにコピーを作成し、それらを追加します。物事をより簡単にするために国のISOコードを追加することを忘れないでください。

App.xaml:文字列と

<Application x:Class="WpfStringTables.App" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
StartupUri="Window1.xaml"> 
    <Application.Resources> 
     <ResourceDictionary > 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="StringResources.de-DE.xaml" /> 
       <ResourceDictionary Source="StringResources.nl-NL.xaml" /> 
       <ResourceDictionary Source="StringResources.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

最後のリソースファイルは、コード内のテキスト部分を置き換えるために使用されます。

3A)Stringテーブルからテキスト部分を使用します。

Window1.xaml

<Window x:Class="WpfStringTables.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <Button Margin="51,82,108,129" Name="AllVehiclesButton" 
       Content="{StaticResource All_Vehicles}"/> 
    </Grid> 
</Window> 

図3b)そうでない場合にのみ、このコードを使用します(コードからリソースをロードXAMLで設定したい):

void PageLoad() 
{ 
    string str = FindResource("All_Vehicles").ToString(); 
} 

4)アプリケーションの開始時に新しい文化にスイッチ:

Codesnippet App.xaml.csから:Creating an Internationalized Wizard in WPF

public static void SelectCulture(string culture)  
{  
    if (String.IsNullOrEmpty(culture)) 
     return; 

    //Copy all MergedDictionarys into a auxiliar list. 
    var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList(); 

    //Search for the specified culture.  
    string requestedCulture = string.Format("StringResources.{0}.xaml", culture); 
    var resourceDictionary = dictionaryList. 
     FirstOrDefault(d => d.Source.OriginalString == requestedCulture); 

    if (resourceDictionary == null) 
    { 
     //If not found, select our default language.    
     requestedCulture = "StringResources.xaml"; 
     resourceDictionary = dictionaryList. 
      FirstOrDefault(d => d.Source.OriginalString == requestedCulture); 
    } 

    //If we have the requested resource, remove it from the list and place at the end.  
    //Then this language will be our string table to use.  
    if (resourceDictionary != null) 
    { 
     Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary); 
     Application.Current.Resources.MergedDictionaries.Add(resourceDictionary); 
    } 

    //Inform the threads of the new culture.  
    Thread.CurrentThread.CurrentCulture = new CultureInfo(culture); 
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture); 

} 
+0

あなたの提案を大好きです。追加するもの: '{StaticResource resKey} 'を使用してアプリケーションを実行時に切り替えることができると思います –

+4

実際には、いつでもリソースを使用する場所でいつでも{DynamicResource resKey}を指定するだけで、いつでも実行時にSelectCultureメソッドを呼び出すと、すべての文字列が新しいカルチャに動的に更新されます。代わりに:文字列str = FindResource( "All_Vehicles")。ToString();使用:Application.Current.Resources ["All_Vehicles"]を文字列として – Curtis

+0

実行時に変更する方法はありますか? – albatross

1

ジョシュ・スミスは、このために彼の好ましい方法についての詳細なチュートリアルを書きました。

大きな再設計(それはMVVM solution)に向いているかもしれませんが、MVVMを使用することは他の理由でも価値があるようです。