やりたいこと
プロジェクトLanguageSwitchSample
はあるユーザーコントロールライブラリWpfControlLibrary1
のDLL
を参照して、参照されたユーザーコントロール画面の多言語対応を実現したい。
サンプルコードダウンロード
パス:Sample/LanguageSwitchSample_DLL/
流れ
LanguageSwitchSample の作成
WPFプログラムの多言語対応を参照して作成する。
又はここからダウンロードする。パス:Sample/LanguageSwitchSample/
WpfControlLibrary1 の作成
-
ソリューションにWPFユーザーコントロールライブラリを追加する
-
lang
フォルダを作成し、言語ファイルen.xaml
とjp.xaml
をしたに置く。(LanguageSwitchSample と区別するため、名前が違う)en.xaml<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib"> <!--新規追加--> <sys:String x:Key="text1">Text1</sys:String> <sys:String x:Key="text2">Text2</sys:String> </ResourceDictionary>
jp.xaml<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib"> <!--新規追加--> <sys:String x:Key="text1">テキスト1</sys:String> <sys:String x:Key="text2">テキスト2</sys:String> </ResourceDictionary>
-
UserControlの画面は簡単で、二つの
TextBlock
だけがあるUserControl1.xaml<UserControl x:Class="WpfControlLibrary1.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfControlLibrary1" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="lang/en.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Text="{DynamicResource text1}" FontSize="40" VerticalAlignment="Center"/> <TextBlock Text="{DynamicResource text2}" FontSize="40" Grid.Row="1" VerticalAlignment="Center"/> </Grid> </UserControl>
-
Class1 の作成
今二つの言語しか使わないので、関数LanguageSwitch
の引数をbool
にした。
実際使うとき、引数をEnum
型にして、複数言語の切替が実現できる。Class1.csusing System; using System.Windows; namespace WpfControlLibrary1 { public interface IWindowInfo { public bool LanguageSwitch(bool isEnglish); } public class Class1:IWindowInfo { private UserControl1 control; public Class1(UserControl1 obj) { control = obj; } public bool LanguageSwitch(bool isEnglish) { ResourceDictionary? langRd = null; string langFile = ""; if (isEnglish) { langFile = "lang/en.xaml"; } else { langFile = "lang/jp.xaml"; } try { // ここは大事! // DLL から リソースディレクトリを使うとき、 // Uri の書き方 new Uri("/現在のプロジェクト名;component/相対パス",UriKind.Relative) langRd = Application.LoadComponent(new Uri("/WpfControlLibrary1;component/" + langFile, UriKind.Relative)) as ResourceDictionary; } catch (Exception ex) { MessageBox.Show(ex.Message); return false; } if (langRd != null) { if (control.Resources.MergedDictionaries.Count > 0) { // 設計画面で言語リソースディレクトリを0番に固定で設定したので control.Resources.MergedDictionaries[0] = langRd; } else { control.Resources.MergedDictionaries.Add(langRd); } } return true; } } }
以上で、クラスライブラリを完成した、次から、LanguageSwitchSample
からWpfControlLibrary1
を呼び出す。
DLLを呼び出す
-
DLL
を参照する - 画面を修正する
下のコードをネームスペースに追加する
xmlns:UserControl="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
画面のサイズは300*300
から300*600
に変更する。
そしてRowDefinition
一行を追加して、呼び出されたユーザーコントロールをここに置く。
一番下でUserControl1
を呼び出すMainWindow.xaml<Window x:Class="LanguageSwitchSample.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:UserControl="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1" xmlns:local="clr-namespace:LanguageSwitchSample" mc:Ignorable="d" Title="MainWindow" Height="600" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition Height="2*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Button Grid.Row="0" Margin="10" FontSize="60" Content="en" Click="Button_en_Click"/> <Button Grid.Row="1" Margin="10" FontSize="60" Content="ja" Click="Button_ja_Click"/> <!--DynamicResource Start ここでkeyの値を読み込む--> <TextBlock Grid.Row="0" Grid.Column="1" FontSize="60" VerticalAlignment="Center" Text="{DynamicResource Start}"/> <TextBlock Grid.Row="1" Grid.Column="1" FontSize="60" VerticalAlignment="Center" Text="{DynamicResource Stop}"/> <UserControl:UserControl1 x:Name="uc1" Grid.Row="2" Grid.ColumnSpan="2"/> </Grid> </Window>
Main画面のクリックイベントを編集する
using System;
using System.Windows;
using WpfControlLibrary1;
namespace LanguageSwitchSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Class1 class1;
public MainWindow()
{
InitializeComponent();
class1 = new Class1(uc1);
}
private void Button_en_Click(object sender, RoutedEventArgs e)
{
ChangeLang(@"lang/english.xaml");
class1.LanguageSwitch(true);
}
private void ChangeLang(string path)
{
ResourceDictionary langRd = null;
string langFile = path;
try
{
langRd = Application.LoadComponent(new Uri(langFile, UriKind.Relative)) as ResourceDictionary;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
if (langRd != null)
{
if (this.Resources.MergedDictionaries.Count > 0)
{
this.Resources.MergedDictionaries[0] = langRd;
}
else
{
this.Resources.MergedDictionaries.Add(langRd);
}
}
}
private void Button_ja_Click(object sender, RoutedEventArgs e)
{
ChangeLang(@"lang/japanses.xaml");
class1.LanguageSwitch(false);
}
}
}
実行結果
en
ボタンを押すと、ユーザーコントロールの文字が英語になる。
ja
ボタンを押すと、ユーザーコントロールの文字が日本語になる。