WPFの文字列リソース(resx)をそのままUWPとXamarin.Formsで共有したおはなし
あすかです。
UWPで国際化(ローカライズ)というと、すでに先人が記事をかかれているとおり、いろいろな方法があります。
これ見てる限り、リソース名は「なんとか.Text」だとか「あーだこーだ.Content」だとか、「ユニーク名+プロパティ名」という形で指定するようですね。
これによって、テキストだけでなく、その他の、なんかの数値や色とかも国際化することができるみたいです。
中国は赤!ロジアは赤!イギリスは黄色!うーん、ロマンチックですね。
ところで、WPFで国際化するときの方法を見てみます。
WPFは、UWPと違ってプロパティ名を指定する必要が無いみたいですね。
みんなそうしてますよね、仕方ないですね。
なお、Xamarin.Formsのローカライズでも、PCLプロジェクトに「AppResources.resx」「AppResources.ja.resx」を作ります。ここはWPFと似ていますね。
UWPでも今までのresxを使いたいんじゃ
さて、ここに、WPFで作ったアプリのリソースファイルがあります。
アプリをWPFからUWPに乗り換えることになりました、さて、これはどうすればいいんでしょうか。
いちいち全項目に「Text」ってつけるんでしょうか。
しかも、TextBlockは「Text」プロパティでいいんですけど、ContentDialogは「PrimaryButtonText」とかですよね。
いちいち直してたら時間かかること間違いなしです。
もちろん、本気でやるならUWPの仕様にあわせるべきですが、こんなのいちいちやってらんねー!ということで、調べました。
WPFと同じ感じで書けない?
ということで、やってみました。
なんか波線が出てますが気にせずコンパイル!
(^ω^)
(^ω^)ペロペロ
グギー!!!!!!
このほかにもStaticResource
、local:Resources.String1
のように直書きしたりもしましたが全てうまくいかず。
マークアップ拡張を自作?
UWPで決められた方法以外の国際化を、しかもXAML上で使うためには、自分でXAMLの機能を拡張しなければいけません。
まず、UWPにマークアップ拡張の独自定義機能が存在するか?WPFやXamarin.Formsではできるんですよね。
ところがどっこい‥‥‥‥
夢じゃありません‥‥‥‥!
UWPのマークアップ拡張は自作できません。
現実です‥‥‥!これが現実‥!
かといってビヘイビアとかで指定すると、XAMLが冗長になってしまいます。
なんとしても、WPFみたいに「<Label Content="{p:Resources.Greeting}">
」みたいな感じで、お手軽に指定したいんです。
CustomResource
次に目をつけたのが、CustomResourceです。
マークアップ拡張を自作できないなら、やっぱりこういうものに頼るしかないです。
この手法は比較的高度なものであり、Windows ランタイム アプリのほとんどのシナリオでは使われていません。
とか書いていますが、無視して使ってみます。
まず、CustomXamlResourceLoader
を継承したクラスを1つ作り、GetResource
メソッドをオーバーライトします。
リフレクションを使っています。System.Reflection
名前空間を使います。
作りましたね?作りました!さて、次にApp.xaml.cs
を開いて、App
クラスのコンストラクタの最初に一行追加します。
はい、これだけです。
次に、XAMLでCustomResourceを呼び出します。
これを実行してみます。
うまくいきました。
まとめ
CustomResourceは、ひとつのアプリで1種類しか指定できないんですよね。
なので、これからまた別の需要が出てきたら、そのときはどうしようかなって不安もあります。
うーん、マークアップ拡張、自作できるようになってほしい!!