.NET デスクトップ アプリケーションのインターナショナリゼーション/ローカライゼーション

概要

このブログでは、2 つの .NET プラットフォーム (Windows Forms と WPF) のインターナショナリゼーションおよびローカリゼーションの例をご紹介します。手順はほとんど同じですがプラットフォームごとに構文が多少異 なります。また ASP.NET もほとんど同じ手順です。ただし、サードパーティ ライブラリが使用される HTML5 や JavaScript などでは方法が全く異なります。

プロジェクトの概要

Windows Forms と WPF でとてもシンプルな UI にラベルとドロップダウンを使用してプ ロジェクトを作成します。これらの要素を使用することにより、インターナショナリゼーションにおける以下の項目をカバーします。

  1. 外部ファイ ルの文字列
  2. UI レイアウトの変更
  3. 文字列等価チェック以外の方法

Windows Forms の例

  1. Visual Studio で新しい Windows Forms プロジェクトを作成します。
  2. ツールボックスの共通コントロール セクションで Label と ComboBox を追加します。lblQuestion と cmbColor と名前を付けます。
  3. ラベルの Text プロパティを "What is your favorite color?" に設定します。UI で水平ではなく垂直に配置します。これは翻訳後のテキストのためにスペースを確保するためです。英語でも既にスペースが ほとんどないため、より長い文字列となる他の言語では見切れが発生する可能性が高いためです。

  4. デザイナーで文字列を Items プロパティに直接追加する代わりに、 コードビハインドで ComboBox に数色追加します。Value プロパティが Text のみでなく各項目と関連付けされます。

    cmbColor.DisplayMember = "Text";
    cmbColor.ValueMember = "Value";
    
    
    var colors = new[] {
       new { Text = "Red", Value = "red" },
       new { Text = "Blue", Value = "blue" },
       new { Text = "Yellow", Value = "yellow" },
       new { Text = "Green", Value = "green" },
       new { Text = "Pink", Value = "pink" }
    };
    
    cmbColor.DataSource = colors;
    
    
  5. SelectedValueChanged イベントにコードを追加し、ユーザーが緑のドロップ ダウン項目を選択したかどうかをチェックします。ここでは "SelectedText" ではなく "SelectedValue" を使用することに注意してくだ さい。ロケールに基づいて変更されない値を含むためにコードで項目を設定しました。

    private void cmbColor_SelectedValueChanged(object sender, EventArgs e)
    {
      if ((string)cmbColor.SelectedValue == "green")
      {
          MessageBox.Show("Green is my favorite color too!");
      }
    }
    
  6. これでですべての設定が終わりました。UI 文字列リソースを外部に出しま す。最初のデザインの前または後に行います。Visual Studio はどちらでも問題ありません。

    1. Form の Localizable プロパティを true に設定し ます。これによりフォーム リソース ファイルが準備されます。
    2. ソリューション エクスプローラーで Form1.resx ファイルを開きます 。質問がここに追加されていることが確認できます。
    3. このファイルをコピーし、ターゲット ロケールのカルチャ コードに基づいて名前を変更します。ここでは日本語 (ja) を例として使用します。
    4. ターゲット ロケール ファイルでは、">>" で始まる項目は重複する必要がないため、すべて削除できます。またその他の項目や画像、ア イコン、ファイルなど、変更する必要のないアイテムも削除できます。次に質問を翻訳します。
  7. コードビハインドの文字列は、 Form1.resx ファイルがデザイナーで自動生成されるため正しく動作しませ ん。デザイナーにない項目を resx ファイルに追加した後にデザイナーを更新すると、.resx ファイルに追加した項目は削除されます。代わりにコードビハイ ンドの文字列のために別のリソース ファイルをプロジェクトに追加します。

    1. コードビハインドでメッセージのキーと値を追加します。色もこ こに追加します。
    2. コピーして名前を変更し、ファイルをプロジェクトに追加します。
    3. コード ビハインドからのエントリを翻訳します。
    4. コード ビハインドのハードコード文字列をこ のリソース ファイルへの参照で置き換えます。更新されたインテリセンスを表示するためにリビルドする必要があるかもしれません。
      private void cmbColor_SelectedValueChanged(object sender, EventArgs e)
      {
         if ((string)cmbColor.SelectedValue == "green")
        {
          MessageBox.Show(Strings.favoriteColorMatch);
         }
      }
      
      var colors = new[] {
        new { Text = Strings.colorRed, Value = "red" },
        new { Text = Strings.colorBlue, Value = "blue" },
        new { Text = Strings.colorYellow, Value = "yellow" },
        new { Text = Strings.colorGreen, Value = "green" },
        new { Text = Strings.colorPink, Value = "pink" }
      };
      
      
  8. プロジェクトをビルドして実行します。

InitializeComponent の前のコンストラクタ で以下のコードを使用して他のロケールをテストできます。

System.Threading.Thread.CurrentThread.CurrentUICulture = new 

System.Globalization.CultureInfo("ja");

WPF の例

  1. Visual Studio で新しい WPF プロジ ェクトを作成します。
  2. ツールボックスの共通 WPF コントロール セクションから、ラベルと ComboBox を XAML ファイルの <Grid> セクションに追加します。lblQuestion と cmbColor と名前を付けます。ラベル の Content プロパティを "What is your favorite color?" に設定します。スタック パネルで垂直に調整できます。ローカライズされたテキスト 用にスペースが取れるからです。

    <Grid>
     <StackPanel VerticalAlignment="Center">
       <Label Content="What is your favorite color?" HorizontalAlignment="Center" 
    Name="lblQuestion" />
       <ComboBox HorizontalAlignment="Center" Name="cmbColor" Width="120" />
     </StackPanel>
    </Grid>
    
    
  3. デザイナーで ComboBox に項目を追加します。テキスト表示のための Content、およびキーのよ うに使用する値のための Tag を設定します。XAML は以下のようになります。

     <ComboBox HorizontalAlignment="Center" Name="cmbColor" Width="120" 
    DropDownClosed="cmbColor_DropDownClosed"> <ComboBoxItem Content="Red" Tag="red" /> <ComboBoxItem Content="Blue" Tag="blue" /> <ComboBoxItem Content="Yellow" Tag="yellow" /> <ComboBoxItem Content="Green" Tag="green" /> <ComboBoxItem Content="Pink" Tag="pink" /> </ComboBox>
  4. DropDownClosed イベン トにコードを追加し、ユーザーが緑のドロップダウン項目を選択したかどうかをチェックします。インターナショナリゼーションでの問題を避けるために、 Content プロパティではなく Tag プロパティをチェックすることに注意してください。

     private void cmbColor_DropDownClosed(object sender, EventArgs e)
     {
         ComboBoxItem cbi = (ComboBoxItem)cmbColor.SelectedItem;
         if (cbi.Tag.ToString() == "green")
         {
             MessageBox.Show(Properties.Resources.favoriteColorMatch);
         }
     }
    
  5. これでですべての設定が終わりました。UI 文字 列リソースを外部に出します。

    1. プロジェクトに含まれる Resources.resx ファイルを開きます。
    2. 質問、コードビハインドのメッセージ、そして色のキーと値を追加します。
    3. コピーして名前を変更し、ファイルをプロジェク トに追加します。
    4. コード ビハインドからのエントリを翻訳します。
    5. XAML ファイルとコードビハインドのハードコード文字列をリソースファイルへの参照で置きえます。名前空間宣言を XAML ファ イルに追加します。
      xmlns:resx="clr-namespace:WPFI18N.Properties"
      
      リソース ファイルのアクセス修飾子を Public に設定してください。
      次に XAML で .resx ファイルへバインドします。
      <Label Content="{x:Static resx:Resources.question}" HorizontalAlignment="Center" 
      Name="lblQuestion" /> <ComboBox HorizontalAlignment="Center" Name="cmbColor" Width="120"
      DropDownClosed="cmbColor_DropDownClosed"> <ComboBoxItem Content="{x:Static resx:Resources.colorRed}" Tag="red" /> <ComboBoxItem Content="{x:Static resx:Resources.colorBlue}" Tag="blue" /> <ComboBoxItem Content="{x:Static resx:Resources.colorYellow}" Tag="yellow" /> <ComboBoxItem Content="{x:Static resx:Resources.colorGreen}" Tag="green" /> <ComboBoxItem Content="{x:Static resx:Resources.colorPink}" Tag="pink" /> </ComboBox>
      コード ビハインド:
      MessageBox.Show(Properties.Resources.favoriteColorMatch);
      
  6. プロジェクトをビルドして実行します。

InitializeComponent の前のコンストラクタで以下のコードを使用して他のロケールをテストできます。

System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("ja");

まとめ

上記 2 つの例では、デスクトップ アプリケーション デザインのテキスト、レイアウト、そして比較について紹介しました。

テストでは、CurrentCulture も変更し、日付や数値の形式などを確認してください。今回のサンプル例には影響しませんが、より複雑なアプリケーシ ョンでは重要なテスト項目です。

また他の言語の場合もメッセージは緑が選択されたときのみ表示されます。そのため、選択された項目のテキストの比 較はしていません。

できるだけ早いタイミングでインターナショナリゼーションをプランニングすることにより、UI のレイアウト変更や比較ロジック を変更するための時間を最小限に抑えることができます。

ローカライゼーション/インターナショナリゼーションとは?

  

以下の 2 つの用語の意味をご存知ですか?

インターナショナリゼーション: 製品を他の言語に現地語化するための前準備といってよいでしょう。これには、文字列や画像リソースの抽出、地域に基づいて数値、日付、時間、通貨形式の適用、テキスト入力の許可、および右から左のサポートなどが含まれます。つまり、ローカライゼーションの前準備のようなものです。用語グローバリゼーションは同じ意味で使用されます。

ローカライゼーション: 製品を特定のロケールに地域化させる翻訳のプロセスです。通常テキスト、そして場合により画像を処理します。レイアウトは新しいコンテンツに合うよう変更しましょう。特定のコンテンツは、特定のカルチャに合うよう変更する必要があるかもしれません。テストは大変重要ですが、特にネイティブ スピーカーによるテストを行うようにしましょう。

i18n や l10n と表記されることもあります。これらの略語は、最初と最後の文字、そしてその間に何文字あるかによってこの用語が構成されています。

ローカライズの必要性

コードはユニバーサル ランゲージですが、UI (ユーザー インターフェイス) が 1 言語のみの場合、潜在市場規模が制限されるでしょう。ユーザーが日本語しか話さない場合、日本語以外のソフトウェアを使用したいと思いますか?もちろん NO ですね?このように知らない言語のアプリケーションを使用したいと思う人はおそらくいないでしょう。そこでローカライゼーションとインターナショナリゼーションの出番です!市場を拡大するとともに、ユーザーの満足度も上げましょう。

ソフトウェア以外の例

上記の広告ですが、どう理解しますか?

  1. 男性が砂漠で疲れ切って倒れています。
  2. ソーダを飲みました。
  3. また走り出しました。

すばらしい広告ですよね?ちょっと待ってください。右から左へ表示する国ではどうなるでしょうか?

  1. 男性が走っています。
  2. ソーダを飲みました。
  3. 砂漠で倒れてしまいました。

これではソーダを飲みたい人はいませんね?

シボレー・ノヴァはスペイン語圏ではあまり売れませんでした。走らない ("no va") という名前の車を買いたいと思う人はいませんね?

この映画は日本で天空の城ラピュタ (Laputa: Castle in the Sky) といいます。欧米では Castle in the Sky に変更されました。スペイン語ではラピュタ (Laputa) が不快な語になりえるからです。

ソフトウェアの例

次のブログはインターナショナリゼーションとローカライゼーションのベストプラクティスについてご紹介する予定です。ソフトウェア開発部分に焦点を当てます。お楽しみに!先に少しだけ紹介しておきますね。

テキスト入力 - テキスト ボックスやコンボ ボックスで英語以外 (アクセント付き文字、中国語、日本語、韓国語、アラビア語など) の文字入力を可能にします。これが可能でないとアプリケーションはその国 (または地域)で利用されることはないでしょう。

レイアウト - 追加スペースを確保します。ドイツ語を含むいくつかの言語は英語より長くなる場合が多いです。入力の上にラベルを配置するのもレイアウトの問題を解決する方法です。

数値、日付、時間、通貨形式 - これらは地域設定に基づいて自動的に書式設定されます。.NET などのライブラリは DateTime.ToShortDateString() などのメソッド でこの機能を提供します。

L10N と I18N のベストプラクティス

このブログでは、ソフトウェアのローカリゼーションとインターナショナリゼーションについて紹介します。ローカリゼーションとインターナショナリゼーションのベストプラクティスと避けるべき事柄について説明します。前回のブログをまだ読んでいない方は是非こちらをお読みください。

開発初期で行うタスク

コーディングは初めからインターナショナリゼーションを念頭に行うべきで、既存のコードをインターナショナリゼーション仕様にするのは効率的ではありません。実際の開発を始める前にインターナショナリゼーションをプランする時間を確保するようにしましょう。プロジェクト マネージャーと共にターゲットとするロケールすべての仕様についてリサーチを行うようにします。関係者の承認が必要な場合、インターナショナリゼーションによる市場拡大効果について説明すると効果的です。これは見込み客の増加、つまり売り上げの増加を意味します。あるいは、サンプル アプリケーションやプロトタイプをターゲット言語を使用して作成し、実際に使用してもらいましょう。

レイアウトの柔軟性

前回のブログでも書きましたがテキストの長さは言語によって異なります。主に 2 つのオプションがあります。

  1. ロケールごとにレイアウトを調整する。
  2. すべてのターゲット言語に十分なスペースを確保する。入力フィールドの上にラベルを配置しスペースを確保する。同じ行にする場合は入力の前に右揃えのテキストを配置する。

英語以外の入力サポート

すべての言語が A から Z のアルファベットのみを使用するわけではありません。英語以外の文字のサポートはとても重要なポイントです。例えば、文字の上のアクセント記号や複数のキーストロークによって 1 文字を入力する言語などもあります (IME 入力)。ターゲット言語のサポートを開発要件に含み、初期段階でテストを行うようにします。

ユニコード エンコーディング

文字が ??? (疑問符) や [] (ブロック) で表示されているのを見たことがありませんか?これは、エンコーディングによる問題の可能性が高いです。ファイルで Unicode (UTF-8) エンコードを使用することをお勧めします。デフォルトで ANSI、またはそれぞれの地域に基づいた他のエンコードを使用するアプリケーションがあります。

カルチャ特有の形式

数値、日付、時間、通貨、更にはカレンダーでも形式が異なることがあります。例えば、千桁の区切りにピリオド(.) を使用するカルチャがあるだけでなく、ほとんどの国や地域で異なる通貨記号を使用しています。また世界のカルチャの多くは、12 時間形式 (AM と PM) ではなく 24 時間形式を使用します。日付はさまざまなバラエティがあります。ヨーロッパでは共通の形式 (日/月/年) が使用されますが、日本では 年/月/日 形式が使用されます。また日本には和暦カレンダー、イスラエルにはヘブライ暦カレンダーがあり、どちらも公式に使用されています。

Right-to-Left (右から左) のサポート

ターゲット ロケールに Right-to-Left (右から左) レイアウトを使用するロケールがある場合、UI でもサポートする必要があります。

ネイティブのレビュー

ローカライズしたアプリケーションをネイティブ スピーカーにレビューしてもらいます。これは、インターナショナリゼーションやローカライゼーションの問題の洗い出しに役立ち、ローカライズした製品で意味が通り、利用できるレベルになります。ローカライゼーションを作業する上で懸念点がある場合は共有し、積極的に意見を交換していきましょう。

注意事項

ハードコードされたテキスト

アプリケーションを適切にインターナショナリゼーションするには、すべてのテキストと画像をプレースホルダーで置き換え (テキストは Lorem Ipsum、画像はサンプル画像を使用)、開発の早い段階でテストを行うことをお勧めします。プレースホルダーが表示されない、プレースホルダーのコンテンツによって何らかの問題が発生するなどの場合は、インターナショナリゼーションが正しく行われていません。これは文字列 (およびその他のリソース) を他のファイル (.NET の場合は .resx ) に抽出することにより簡単に処理できます。次にプレースホルダー コンテンツでファイルのコピーを作成し、必要なロケールでテストします。この方法では実際のコンテンツを変更する必要がなく、テストがパスしたら内部でローカライズまたは翻訳を外注することによってローカライズを進めます。例えば、デフォルト ロケールのみで可能なコード ビハインドで文字列の等価チェックを行います。開発関連の問題の修正は、早ければ早いほどそれにかかるリソースやコストが少なくて済みます。

不適切なコンテンツ

文化によって物事のとらえ方が異なります。たとえば色や記号の意味は文化によって異なります。また、戦争の歴史や領土問題など文化的に敏感になりやすい事柄には注意しましょう。そのため、ターゲット カルチャに合わせてコンテンツを調整することも重要です。

画像テキスト

画像にテキストは使用しないようにしましょう。これにより画像を再使用できる可能性が高まります。テキストが必要な場合は画像をオーバーレイすることにより、画像を変更する必要がなくなります。

連結した文字列

単語の順序は言語によって異なります。この違いは UX に大きな影響を与えます。例えば、favoriteColor という文字列があるとします。この文字列を使用した文、「"私の好きな色は"+ favoriteColor」の語順がすべての言語で通用するとは限りません。何色かを表す単語が英語のように文の最後にくるとは限らないからです。その他、文字列補間を使用してプレースホルダーを訳と置き換えることもできます。これによって何が付加されるのかが明確になります。これは、「"私の好きな色は" + favoriteColor + "です。"」 とプレースホルダーを使用することにより、favoriteColor を必要に応じて移動させることができます。

レイアウトでスペースの使用

テキストの表示を調整にはラベルにスペースは追加するのではなく、テキストの配置プロパティを使用します。余分にスペースを取ることが適切でない理由は、言語によってテキストの長さが異なるためです。また、各言語にそれぞれスペースがどれぐらい必要かをチェックするのは効率的ではありません。これは OS やブラウザーのデフォルト フォント設定によって異なります。

誤解を招きやすいコンテンツ

わかりやすいコンテンツを心がけましょう。翻訳を外注する場合、翻訳者にできるだけ情報を与えることによってローカライズした製品の品質を向上できます。俗語 (スラング) や略語の使用は誤解を招く可能性があるだけでなく、結果的に質の悪いローカライズ製品となります。スペースの制限によって略語を使用しなければならない場合、デザインを変更することもできますが、文字数制限を翻訳者にコメントなどを使用して明確に伝える必要があります。更に意味が分かりにくいような単語には、その単語が UI で使用される目的などを明確に翻訳者に伝えましょう。例えば、単語 「last」には、動詞の「続く」、形容詞の「最後の」、副詞の「この前に」などの意味があります。異なる意味を持つ単語のみを UI で使用する場合は、リソース ファイルにメモなどを残して翻訳者が意味を正しく取れるようにサポートしましょう。