スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: スポンサー広告

多言語化、或いはローカライズ(四)

 前回の多言語化、或いはローカライズ(参)で、ローカライズにリソースファイルを使てみた。これ以外にやるのであれば、外のファイルに出すか、データベース内のテーブルに持たせるくらいかな。仕事ではデータベース内のテーブルを基本として、使ったリソースは、ローカルファイルにキャッシュする方法を採っている。
 文字列リソースをデータベースに持たせる理由は、他の複数のプロジェクトと共有する事。企業は、内部に固有の単語を持ち、それで話(打ち合わせ)をすることが多い。そうでなくても共通な単語は多い。例えば、部門、社員、営業、販売、勘定科目、等々。共通的な単語はそうそう変わらない。でも、ローカルな単語、特に新しく作られた単語はコロコロ変わる。開発中に変わると非常にめんどくさい。この単語を開発画面のあちこちに使っていると、逐一検索して修正するという手間が発生する。
 そういう手間をなくす為の共有化なんだけど、上でやった実装方法では、共有化が難しい。
  ・TranslateManagerが扱えるプロバイダ(リソースファイル)が1つだけ。
  ・複数持てたとしても、マークアップを使用するとき、どのリソースを使うかを指定する必要がある。
リソースを共有する為だけのライブラリプロジェクトを作ったとして、それを参照できる方法が必要なので、そういう感じに実装を変更してみる。

○TranslationManagerクラス
変更点:内部で持つプロバイダーオブジェクトを複数にする。
/// <summary>プロバイダーディクショナリ</summary>
private Dictionary<string, ITranslationProvider> transProvidors_;

コンストラクタでインスタンスを生成する。
/// <summary>
/// コンストラクタ(private)
/// </summary>
private TranslationManager() {
this.transProvidors_ = new Dictionary<string, ITranslationProvider>();
return;
}

TranslationProviderプロパティを削除、代わりにデフォルト用のプロパティを用意する。
/// <summary>
/// デフォルトの置き換え情報提供オブジェクトを取得|設定します。
/// </summary>
public ITranslationProvider DefaultTranslationProvider {
get; set;
}

プロバイダを追加する為のメソッドを実装する。
/// <summary>
/// プロバイダーを追加します。
/// </summary>
/// <param name="key">登録用キー</param>
/// <param name="newProvidor">文字列置き換えプロバイダ</param>
/// <param name="useAsDefault">true:デフォルトして使う</param>
public void AddTrasnlateProvidor(
string key,
ITranslationProvider newProvidor,
bool useAsDefault = false) {

if (Utils.IsEmptyOrWhiteSpace(key)) {
throw new ArgumentNullException("key");
}

if (newProvidor == null) {
throw new ArgumentNullException("newProvidor");
}

this.transProvidors_[key] = newProvidor;

//デフォルトとして使う為、プロパティにも設定します。
if (useAsDefault) {
this.DefaultTranslationProvider = newProvidor;
}

return;
}

Translateメソッドを改造する。
/// <summary>
/// 指定キーで置き換えられるオブジェクトを取得します。
/// </summary>
/// <param name="key">指定キー</param>
/// <param name="providorKey">プロバイダーを指定するキー</param>
/// <returns>置き換えられるオブジェクト</returns>
public object Translate(string key, string providorKey = null) {

//providorKeyキー指定無しの時は、デフォルトのプロバイダーを使用します。
//デフォルトがないときは、総当りで。
if (Utils.IsEmptyOrWhiteSpace(providorKey)) {

if (this.DefaultTranslationProvider != null) {
var val = this.DefaultTranslationProvider.Translate(key);

if (val != null) {
return val;
}
} else {
foreach (var providor in this.transProvidors_.Values) {
var val = providor.Translate(key);

if (val == null) {
continue;
} else {
return val;
}
}
}

} else if (this.transProvidors_.ContainsKey(providorKey)) {
var providor = this.transProvidors_[providorKey];

var val = providor.Translate(key);

if (val != null) {
return val;
}
}

//取得に失敗している事を見た目でわかるようにする。
return string.Format("!{0}!", key);
}

○TranslationDataクラス
Valueプロパティを改造する。受け取ったキーを「(プロバイダキー)-(リソースキー)」という扱いにする。ハイフン(-)にしたのは、リソースキーにそれを設定できないため。
/// <summary>
/// キー文字列に対応した(置き換えられる)オブジェクトを取得します。
/// </summary>
public object Value {
get {
if (this.key_.Contains("-")) {
var provAndKey = this.key_.Split('-');

return TranslationManager.Instance.Translate(provAndKey[1], provAndKey[0]);

} else {
return TranslationManager.Instance.Translate(this.key_);
}
}
}
ハイフンが含まれなければ、デフォルトのプロバイダを参照しにいく事になる。
○実行時
実行時に、プロバイダーをキーと共に設定する。
リソースファイル(TawamureDays.WPFTest)
20130601_3
リソースファイル(TawamureDays.Resources)
20130601_4

起動時にプロバイダを登録する。
//TawamureDays.WPFTestプロジェクトのリソースクラス
TranslationManager.Instance.AddTrasnlateProvidor(
"DEF",
new ResxTranslationProvider(
typeof(TawamureDays.WPFTest.Properties.Resource)),
true);
//TawamureDays.Resourcesプロジェクトのリソースクラス
TranslationManager.Instance.AddTrasnlateProvidor(
"RES",
new ResxTranslationProvider(
typeof(TawamureDays.Resources.Properties.Resource)));

XAML上では、こんな感じになる。
<DockPanel>
<tw:TwContents>
<StackPanel>
<Button Content="{tw:Trans Key=DEF-FIRST_BUTTON, Default=最初のページへ2}"/>
<Button Content="{tw:Trans Key=RES-CAPTION_OK, Default=OK}"/>
</StackPanel>
</tw:TwContents>
</DockPanel>
実行
20130601_5
共有したい単語は、TawamureDays.Resourcesの方、このプロジェクトでしか使わなさそうなマイナーな単語は、TawamureDays.WPFTestの方に登録して使っていく事になる。分けたら分けたで、管理が大変にはなるけど。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。