質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

4回答

8093閲覧

動的に変化する文字列を国際化対応する方法について教えてください。

samusaku

総合スコア34

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2016/11/08 00:52

###前提・実現したいこと
動的に変化する文字列についてOSの言語によって日本語、英語に切り替えたいです。

静的な文字列(Buttonの名前等)であれば、日英ぞれぞれのResources.resxを用意して、
「データバインドを利用する」で設定できることは分かったのですが、
動的な文字列の場合の言語切り替え方法がわからず、悩んでいます。

サンプル実装を記載いたしました。
動的な文字列は
label.Content = m_Count + " 回押されました";
のように埋め込み文字列で実装しています。

これを実行して該当ボタンを押下すると、

日本語OSなら、
1回押されました。

英語OSなら
1 pushed.

みたいにしたいと考えています。

お手数ですが、ご教授お願いいたします。

###該当のソースコード
XAML

<Window x:Class="test111.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:test111" mc:Ignorable="d" Title="MainWindow" Height="187.255" Width="356.373"> <Grid> <Button x:Name="button" Content="ボタン1" HorizontalAlignment="Left" Margin="142,93,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> <Label x:Name="label" Content="" HorizontalAlignment="Left" Margin="85,21,0,0" VerticalAlignment="Top" Height="52" Width="235" FontSize="20"/> </Grid> </Window>

C#

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace test111 { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { private int m_Count = 0; public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { m_Count++; label.Content = m_Count + " 回押されました"; // ←この動的文字列を言語切り替えしたい! } } }

###補足情報(言語/FW/ツール等のバージョンなど)
環境 Visual Studio 2013

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

sk_3122さんの回答のようにするのがよいと思いますが蛇足的な補足を。

とりあえず日本語と英語のみとした場合、語順の違いは簡単に吸収できます。ただ違いを吸収できない(というより英語のみに限定したとしても簡単にメッセージを生成できない)パターンがあります。ご存知のように英語で単数形と複数形で厳密には単語語尾がかわりますよね?

pushed 1 time.
pushed 2 times.

計算機言語の中にはこうした単語の変化にまで対応したものがあります(例えばCommonLispには英語のみに対応した語尾変化対応機能があります)が、そんな機能は珍しくまた多国語を共通に使えるものでもないと思います。語尾変化を以下のような形でごまかしているようなメッセージもみることがありますが・・・

pushed {0} time(s).

計算機で自然言語をうまく表現するにも限界があるので、語尾変化などは文面を作る際に工夫する(そして多少おかしな文になっても読み手が許してくれる)と割り切ってFormatを使う方法を取るのがよいと思います。

投稿2016/11/08 02:31

編集2016/11/08 02:55
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんにちは。

多言語化自体はC#一般の方法でやっていて、その多言語化した文字列の一部をバラメータで与えたいわけですね。
そのような時はString.Format()がたいへん便利です。

例えば、"Please refer to Section 3 in 15 pages."のようなメッセージの3と15をバラメータにしたい場合、下記のようにします。

string mess=string.Format("Please refer to Section {0} in {1} pages.", section_no, page_no);

自然な日本語としては、「15ページの第3節を参照下さい。」のように訳したいです。
15と3の順序が逆なのでちょっと工夫が必要です。引数順指定を使えば下記のように簡単に対応できます。
先程のstring.Format()の"Please refer to Section {0} in {1} pages."の部分を"{1}ページの第{0}節を参照下さい。"に置き換えるだけです。

この考え方は新しいものではなく、広く使われています。
私はlinux界隈のgettext方式の一部として知りました。
C#のstring.Format()の引数準指定機能って最初に知った時は冗長な印象でしたが、多言語化する時には必要な機能と思います。

投稿2016/11/08 02:34

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

samusaku

2016/11/08 11:48

なるほど。埋め込み文字列の位置も言語によって考慮しないと意味が通らないメッセージになってしまいますね。String.Formatを使い、文字の中身はResourceに登録してやってみようと思います。ありがとうございました!!
guest

0

リソースに"CountMessage"など任意で文字列リソースを追加して

label.Content = m_Count + Properties.Resources.CountMessage;

でできますよ。

投稿2016/11/08 01:01

KIYOSHI

総合スコア268

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Resources.resx に置換用のフォーマット文字列?を定義しておくのじゃダメですかね?

var pushedMessage = "{0} 回 あるいは {1} 回押されました"; //var pushedMessage = "{0} or {1} pushed."; var str = string.Format(pushedMessage, 3, 4); // 置換する Console.WriteLine("[" + str + "]"); // 確認

投稿2016/11/08 01:02

編集2016/11/08 02:55
sk_3122

総合スコア1126

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2016/11/08 02:40

Resources.resxはプラットフォームのエンコーディングにより自動的に切り替わる機構(質問者さんご自身がおっしゃっている方法)が標準で用意されているのでそれを生かしたままの回答でよいのではないでしょうか?閲覧者の方が「自分で配列を用意しなければならない」と勘違いするような気がします。
sk_3122

2016/11/08 03:03

質問者さんじゃなくて Resources.resx を知らない他の閲覧者が勘違いするということですね。 直しました。まあサンプルとしても for 文じゃない方がすっきりしますね。
sk_3122

2016/11/08 04:25

エンジニア・Webデザイナー必読: アプリケーションを国際化・多言語展開する前に知っておくべきこと http://qiita.com/hachi8833/items/4666638e930de65dcdef > ではどうすればいいのか? コロンだ、コロンを使うのだ! の辺りとか参考になりました。なるほど…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問