トップ回答者
アプリケーションの起動中にフォームのカルチャを変更するには?

質問
-
ユーザーが設定変更するとフォームのカルチャを変更できるようにしたいと考えています。
現在の状況は、・フォームのメニュー等がリソースファイルによりローカライズされている。
・フォーム上のツリーボックスにはカルチャに依存する日付などのデータが表示される。
・カルチャの設定はアプリケーションのスタートアップイベントで行っており、これはうまくいっている。
更にアプリケーションの起動後にユーザーがカルチャを変更できるようにしたいと考え、
My.Application.ChangeUICulture("CultureCode")
My.Application.ChangeCulture("CultureCode")
のようにしたのですが、表示は変更されません。おそらくフォームを初期化しなければならないのだと想像しているのですが
方法がわかりません。
どのようにしたら良いか、ご教示願えないでしょうか。
回答
-
ふーじあ さんからの引用 ところが、一度Form1が表示された後にカルチャを変更しても、Form1の表示が変更されないのが
悩みとなっています。
ChangeCulture、ChangeUICultureは次にリソースから文字列等を引っ張ってくる際のカルチャ情報を変更するものです。
従って、既に表示されているフォームには影響しません。(そういうものです)
フォームは初期化時にInitializeComponentにてApplyResourcesメソッドを使って、リソースから情報を取得しています。
これと同じことをすれば良いという論理になりますが、果たして本当に問題ないのかが分かりません。
やって良いとしても、フォームやコントロールについて1つずつApplyResourcesを実行しなければならず、保守の手間がかかります。
-
実行時に反映するためには、ApplyResources を実行する必要があるようです。
Code SnippetDim resources As New System.ComponentModel.ComponentResourceManager(Me.GetType())
'resources.IgnoreCase = True
resources.ApplyResources(Me, "$this")
resources.ApplyResources(Me.Button1, "Button1")
'・・・.Designer.vb の中にある ApplyResources の行をすべて# かぶった上に、情報量が少ない
-
以下のようにしてカルチャの更新ができました。
(なお、支障がないかの確認はまだしていません)
コントロールの種類が増えればコードも増加し、確かに保守が煩雑になります。
Private Sub UpdateCulture()
'現在のカルチャの変更My.Application.ChangeUICulture(My.Settings.CultureCode)
My.Application.ChangeCulture(My.Settings.CultureCode)
Dim resources As System.ComponentModel.ComponentResourceManager = _New System.ComponentModel.ComponentResourceManager(GetType(Form1))
'フォーム内のコントロールのカルチャの更新
Me.RecursiveControlCultureUpdate(Me, resources)'MenuStrip内のToolStripMenuItemのカルチャの更新
For Each tsmi As ToolStripMenuItem In Me.MainMenuStrip.Items
Me.RecursiveToolStripMenuItemCultureUpdate(tsmi, resources)
Next'フォーム自身のカルチャの更新
resources.ApplyResources(Me, "$this")'以下、その他の種類のコントロールのカルチャを更新するコード
End Sub
'フォーム内に含まれるコントロールのカルチャを再帰的に更新する
Private Sub RecursiveControlCultureUpdate(ByVal control As Control, ByVal resources As _System.ComponentModel.ComponentResourceManager)
resources.ApplyResources(control, control.Name)
For Each c As Control In control.Controls
RecursiveControlCultureUpdate(c, resources)
Next
End Sub' メニューストリップ内に含まれるToolStripMenuItemのカルチャを再帰的に更新する
Private Sub RecursiveToolStripMenuItemCultureUpdate(ByVal tsmi As ToolStripMenuItem, _ByVal resources As System.ComponentModel.ComponentResourceManager)
resources.ApplyResources(tsmi, tsmi.Name)
For Each mi As ToolStripMenuItem In tsmi.DropDownItems
Me.RecursiveToolStripMenuItemCultureUpdate(mi, resources)
Next
End Sub
すべての返信
-
こちらで試してみましたが、特にフォームを初期化しなくても表示が変更されました。とりあえず参考になりそうなページを紹介しておきます。
Visual Basic 2005 を使って、プログラムによって Windows ベースのアプリケーションにカルチャ情報を設定する方法
http://support.microsoft.com/kb/914356/ja -
少し質問があいまいでした。
(教えていただいたページのサンプルコードは上手くいきました)
私の場合、
アプリケーションのメインフォーム(Form1)のLocalizableプロパティをTrueとし、
メニューやコントロールの文字を「既定の言語」では英語で作成しています。(例:Button1)
次にForm1のLanguageプロパティをたとえばja-JPにした上で、
メニューやコントロールの文字を日本語に変更します(例:ボタン1)。
(Form1.ja-JP.resxというファイルが自動的に作成されます。)
このようにした上で、アプリケーションのスタートアップ時(つまりForm1が生成される前に)
カルチャーをja-JPに設定すれば日本語が、その他のカルチャにすればその他の言語が
表示されるようになっています。
ところが、一度Form1が表示された後にカルチャを変更しても、Form1の表示が変更されないのが
悩みとなっています。
なお、変更するためのコードとしては最初の質問のように
My.Application.ChangeCulture("ja-JP")
My.Applicatioin.ChangeUICulture("ja-JP")
としています。
-
ふーじあ さんからの引用 ところが、一度Form1が表示された後にカルチャを変更しても、Form1の表示が変更されないのが
悩みとなっています。
ChangeCulture、ChangeUICultureは次にリソースから文字列等を引っ張ってくる際のカルチャ情報を変更するものです。
従って、既に表示されているフォームには影響しません。(そういうものです)
フォームは初期化時にInitializeComponentにてApplyResourcesメソッドを使って、リソースから情報を取得しています。
これと同じことをすれば良いという論理になりますが、果たして本当に問題ないのかが分かりません。
やって良いとしても、フォームやコントロールについて1つずつApplyResourcesを実行しなければならず、保守の手間がかかります。
-
実行時に反映するためには、ApplyResources を実行する必要があるようです。
Code SnippetDim resources As New System.ComponentModel.ComponentResourceManager(Me.GetType())
'resources.IgnoreCase = True
resources.ApplyResources(Me, "$this")
resources.ApplyResources(Me.Button1, "Button1")
'・・・.Designer.vb の中にある ApplyResources の行をすべて# かぶった上に、情報量が少ない
-
以下のようにしてカルチャの更新ができました。
(なお、支障がないかの確認はまだしていません)
コントロールの種類が増えればコードも増加し、確かに保守が煩雑になります。
Private Sub UpdateCulture()
'現在のカルチャの変更My.Application.ChangeUICulture(My.Settings.CultureCode)
My.Application.ChangeCulture(My.Settings.CultureCode)
Dim resources As System.ComponentModel.ComponentResourceManager = _New System.ComponentModel.ComponentResourceManager(GetType(Form1))
'フォーム内のコントロールのカルチャの更新
Me.RecursiveControlCultureUpdate(Me, resources)'MenuStrip内のToolStripMenuItemのカルチャの更新
For Each tsmi As ToolStripMenuItem In Me.MainMenuStrip.Items
Me.RecursiveToolStripMenuItemCultureUpdate(tsmi, resources)
Next'フォーム自身のカルチャの更新
resources.ApplyResources(Me, "$this")'以下、その他の種類のコントロールのカルチャを更新するコード
End Sub
'フォーム内に含まれるコントロールのカルチャを再帰的に更新する
Private Sub RecursiveControlCultureUpdate(ByVal control As Control, ByVal resources As _System.ComponentModel.ComponentResourceManager)
resources.ApplyResources(control, control.Name)
For Each c As Control In control.Controls
RecursiveControlCultureUpdate(c, resources)
Next
End Sub' メニューストリップ内に含まれるToolStripMenuItemのカルチャを再帰的に更新する
Private Sub RecursiveToolStripMenuItemCultureUpdate(ByVal tsmi As ToolStripMenuItem, _ByVal resources As System.ComponentModel.ComponentResourceManager)
resources.ApplyResources(tsmi, tsmi.Name)
For Each mi As ToolStripMenuItem In tsmi.DropDownItems
Me.RecursiveToolStripMenuItemCultureUpdate(mi, resources)
Next
End Sub