web-dev-qa-db-ja.com

WPFの多言語

WPFアプリに多言語システムを実装するための良い方法をお勧めできますか?私が現在使用しているメソッドには、XML、クラス、およびxaml拡張機能が含まれます。ほとんどの場合は正常に機能しますが、動的ラベルまたは動的テキストを一般的に処理する必要がある場合は、追加の作業が必要になります。プログラマーにメインの問題だけで作業させ、langの問題を忘れさせたいと思います。

22
Jonathan

WPFローカリゼーション拡張機能 を使用しています。 DependencyPropertysで任意のタイプのDependencyObjectをローカライズするのは本当に簡単な方法です。

  • 本当に安定した状態です
  • Text = {LocText ResAssembly:ResFile:ResKey}のようなバインディングのような文体をサポートします
  • .resx-フォールバックメカニズムで動作します(例:en-us-> en->独立したカルチャ)
  • 文化の強制をサポートします(例:「これは常に英語である必要があります」)
  • 通常の依存関係プロパティで動作します
  • コントロールテンプレートで動作します
  • 追加の名前空間なしでXAML(実際には:P)で使用できます
  • コードビハインドで使用して、ローカライズされた値を動的に生成されたコントロールにバインドできます
  • 高度な使用のためにINotifyPropertyChangedを実装します
  • 文字列のフォーマットをサポートします。 "this is the '{0}' value"
  • プレフィックスとサフィックスの値をサポートします(現在はLocText拡張子付き)
  • 生産システムで使用されています(私の広報製品のように)
  • 言語をランタイムに切り替えると、[〜#〜] no [〜#〜]タイムスライスに影響します
  • すべてのアセンブリ(実行時に動的にロードされたものも)の任意のリソースファイル(.resx)で使用できます。
  • 初期化プロセスは必要ありません(「xyzを呼び出して特別なローカライズ辞書を登録する」など)
  • 設計時に利用可能です(MS Expression Blend、MS Visual Studio 2008(NormalおよびSP1)
  • 選択した言語の変更は設計時に可能です
  • コンバーター(TypeConverter)が存在する(LocalizeExtensionを拡張する)限り、任意のタイプのデータ型をローカライズできます。
  • Text、upper Text、lower TextImages、Brushes、Double、およびThicknessのサポートが組み込まれています。
  • メモリリークには影響しません
  • UIDプロパティはそのままにします
  • SpecificCultureとして使用するIFormatProviderを提供します(例:(123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20"または"123,20"
  • コードビハインドでリソース値をチェックして取得するためのいくつかの機能を提供します
  • Thread.CurrentCultureまたはThread.CurrentUICultureのカルチャを変更しません(簡単に変更できます)
17
CSharper

次の手順を実行します:

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>

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

a)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>

b)コードからリソースをロードします(XAMLを介して設定したくない場合にのみ、このコードを使用してください):

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

4)アプリケーションの開始時に新しいカルチャに切り替えます:

App.xaml.csからのコードスニペット:

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);

}
34

Josh Smithは、このための彼の好ましい方法について詳細なチュートリアルを作成しました: 国際化されたWizard in WPF の作成。

大幅な再設計( MVVMソリューション )を示すかもしれませんが、MVVMを使用することは他の理由でも価値があるようです。

1
Wilka

この記事を使用して、リソースファイルを簡単に使用して多言語のWPFウィンドウを処理することができました。 http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx 非常にシンプルで効果的であるため、チェックする必要があります。

1
Terenzio Berni