XamPropertyGrid のプロパティ名、説明、およびカテゴリのローカライズ
私は、WPFでEnumの説明をローカライズしてxamPropertyGridに対応する方法に関する私のブログ記事を適応させることができるかどうかを確認したかったのですが、DisplayNameとCategoryもローカライズすることでもう少し進めます。
先日、Infragistics WPFフォーラムを閲覧していて、xamPropertyGridコントロールのプロパティの説明をローカライズする方法を尋ねるこの質問に遭遇しました。
元のポスターでは、属性の使用を含む他のソリューションを検討していましたが、それらのソリューションは複雑すぎてあまり単純ではないと考えていました。 もちろん、私が最初に思ったのは、「それなら、それは間違っている」ということでした。 そこで、WPF で Enum の説明をローカライズして xamPropertyGrid に対応する方法に関するブログ投稿を適応させることができるかどうかを確認したかったのですが、DisplayName と Category もローカライズすることでもう少し進めます。 つまり、私たちは多くのプロパティ情報を持つプロパティグリッドにいますが、なぜ説明だけをローカライズするのですか? いやいや、すべてをローカライズしましょう!
ローカリゼーションサポートの追加
私の最初のステップは、他の投稿のLocalizedDescriptionAttributeを「そのまま」使用して、それがうまくいくかどうかを確認することでした。 そこで、このクラスをコピーしてプロジェクトに貼り付けました。
public class LocalizedDescriptionAttribute : DescriptionAttribute
{
readonly ResourceManager _resourceManager;
readonly string _resourceKey;
public LocalizedDescriptionAttribute(string resourceKey, Type resourceType)
{
_resourceManager = new ResourceManager(resourceType);
_resourceKey = resourceKey;
}
public override string Description
{
get
{
string description = _resourceManager.GetString(_resourceKey);
return string.IsNullOrWhiteSpace(description) ? string.Format("[[{0}]]", _resourceKey) : description;
}
}
}
次に、プロパティの DisplayName と Category のサポートを追加したいと思います。 そこで、LocalizedDescriptionAttribute に使用したのと非常によく似たアプローチを使用する他の 2 つのクラスを作成しました。
LocalizedDisplayNameAttributeは、ほとんど同じように見えます。
public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
readonly ResourceManager _resourceManager;
readonly string _resourceKey;
public LocalizedDisplayNameAttribute(string resourceKey, Type resourceType)
{
_resourceManager = new ResourceManager(resourceType);
_resourceKey = resourceKey;
}
public override string DisplayName
{
get
{
string displayName = _resourceManager.GetString(_resourceKey);
return string.IsNullOrWhiteSpace(displayName) ? string.Format("[[{0}]]", _resourceKey) : displayName;
}
}
}
ただし、LocalizedCategoryAttributeには若干の変更が加えられています。 GetLocalizedString メソッドをオーバーライドする必要がありました。 それ以外は、ロジックは同じです。
public class LocalizedCategoryAttribute : CategoryAttribute
{
readonly ResourceManager _resourceManager;
readonly string _resourceKey;
public LocalizedCategoryAttribute(string resourceKey, Type resourceType)
{
_resourceManager = new ResourceManager(resourceType);
_resourceKey = resourceKey;
}
protected override string GetLocalizedString(string value)
{
string category = _resourceManager.GetString(_resourceKey);
return string.IsNullOrWhiteSpace(category) ? string.Format("[[{0}]]", _resourceKey) : category;
}
}
これで、プロジェクトにいくつかの Resource.resx ファイルを追加し、目的のカルチャをターゲットにすることができます。 英語と日本語(日本語)に対応しています。

PersonResources.resx(英語)

PersonResources.ja-JP.resx (Japanese)

リソースがあるため、ローカライズを開始するにはいくつかのプロパティが必要です。 ここではシンプルにし、1 つのプロパティを持つ Person クラスを使用します。
public class Person
{
[LocalizedDisplayName("NameDisplayName", typeof(PersonResources))]
[LocalizedDescription("NameDescription", typeof(PersonResources))]
[LocalizedCategory("PersonCategory", typeof(PersonResources))]
public string Name { get; set; }
}
アプリを実行して、何があるか見てみましょう。 デフォルトは英語のリソースです。 これは、表示されているすべての値が PersonResources.resx ファイルから取得されていることを意味します。

日本語にローカライズされた値を使用するように変更したい場合はどうなりますか? さて、調べてみましょう。 App.xaml.csを開き、スタートアップ方法をオーバーライドして、カルチャを変更します。
protected override void OnStartup(StartupEventArgs e)
{
CultureInfo info = new CultureInfo("ja-JP");
Thread.CurrentThread.CurrentCulture = info;
Thread.CurrentThread.CurrentUICulture = info;
}
Now, run the applications again.

魅力のように機能します! 私たちの値が PersonResources.ja-JA.resx ファイルに保存されている日本語のリソースから取得されていることは明らかです。
かなり洗練されていますよね? これは複雑すぎるとか、理解するのが難しいとか、まったく難しいとは思いません。 私にはかなりまっすぐに見えます。 どう思いますか。 うまくいけば、これが便利であることがわかり、WPFアプリケーションでこのアプローチを使用することさえできるでしょう。 必ずソースコードをチェックして、遊んでみてください。 いつものように、私のブログでお気軽に私に連絡するか、Twitter(@brianlagunas)で私とつながるか、質問やコメントがある場合は下にコメントを残してください。