1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

WPF DLL化したユーザーコントロール画面多言語対応

Last updated at Posted at 2023-01-20

やりたいこと

プロジェクトLanguageSwitchSampleはあるユーザーコントロールライブラリWpfControlLibrary1DLLを参照して、参照されたユーザーコントロール画面の多言語対応を実現したい。

サンプルコードダウンロード
パス:Sample/LanguageSwitchSample_DLL/

流れ

以下のファイルを作成する
image.png

LanguageSwitchSample の作成

WPFプログラムの多言語対応を参照して作成する。
又はここからダウンロードする。パス:Sample/LanguageSwitchSample/

WpfControlLibrary1 の作成

  1. ソリューションにWPFユーザーコントロールライブラリを追加する

  2. langフォルダを作成し、言語ファイルen.xamljp.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>
    
    
  3. 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>
    
    
  4. Class1 の作成
    今二つの言語しか使わないので、関数LanguageSwitchの引数をboolにした。
    実際使うとき、引数をEnum型にして、複数言語の切替が実現できる。

    Class1.cs
    using 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を呼び出す

  1. DLLを参照する
  2. 画面を修正する
    下のコードをネームスペースに追加する
    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画面のクリックイベントを編集する

MainWindow.xaml.cs
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ボタンを押すと、ユーザーコントロールの文字が英語になる。
image.png
jaボタンを押すと、ユーザーコントロールの文字が日本語になる。
image.png

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?