아래 코드들로 다국어 지원 기능을 구현하기 위해 각 요소가 하는 역할을 단계별로 설명드리겠습니다.
1. 프로젝트 구조
프로젝트에는 각 언어별 ResourceDictionary
파일을 준비해 두었습니다. 예를 들어 ResourceDictionary.ko-KR.xaml
, ResourceDictionary.ja-JP.xaml
, ResourceDictionary.es-EU.xaml
파일을 만들어 각 언어에 맞는 문자열을 저장합니다.
- 예: ResourceDictionary.ko-KR.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="EXPLAIN_01">모든 요소들은 제거됩니다.</system:String>
<system:String x:Key="EXPLAIN_02">폴더에 같은 이름의 파일이 존재합니다.</system:String>
</ResourceDictionary>
- 예: ResourceDictionary.ja-JP.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="EXPLAIN_01">すべての要素が削除されます。</system:String>
<system:String x:Key="EXPLAIN_02">同じ名前のファイルがフォルダに存在します。</system:String>
</ResourceDictionary>
- 예: ResourceDictionary.es-EU.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="EXPLAIN_01">Todos los elementos serán eliminados.</system:String>
<system:String x:Key="EXPLAIN_02">Un archivo con el mismo nombre existe en la carpeta.</system:String>
</ResourceDictionary>
- 예: ResourceDictionary.en-US.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="EXPLAIN_01">All elements will be removed.</system:String>
<system:String x:Key="EXPLAIN_02">A file with the same name already exists in the folder.</system:String>
</ResourceDictionary>
이처럼 각 파일에 특정 언어에 해당하는 리소스를 정의합니다. 이 리소스들은 프로그램에서 DynamicResource
로 불러올 수 있습니다.
2. App.xaml 설정
App.xaml
파일에서 초기 리소스 딕셔너리를 설정합니다. 기본적으로 사용될 리소스들을 지정하며, 프로그램 실행 중 MergedDictionaries
에 추가된 리소스를 변경하면 UI가 자동으로 갱신됩니다.
- App.xaml
<Application x:Class="test241106_ResouceDictionary.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:test241106_ResouceDictionary"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- 초기 상태에서 ko-KR을 기본으로 설정 -->
<ResourceDictionary Source="ResourceDictionary.ko-KR.xaml" />
<ResourceDictionary Source="ResourceDictionary.ja-JP.xaml" />
<ResourceDictionary Source="ResourceDictionary.es-EU.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
여기서는 ResourceDictionary.ko-KR.xaml
, ResourceDictionary.ja-JP.xaml
, ResourceDictionary.es-EU.xaml
을 포함하지만, 실행 중에 코드로 각 리소스를 교체할 수 있습니다.
3. MainWindow.xaml UI 설정
MainWindow.xaml
파일에서는 언어를 선택할 수 있는 ComboBox
와 Button
을 추가하고, 각 UI 요소가 DynamicResource
를 통해 텍스트를 표시하도록 설정합니다.
- MainWindow.xaml
<Window x:Class="test241106_ResouceDictionary.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ResourceDictionary Example" Height="200" Width="600">
<Grid>
<!-- ComboBox로 언어 선택 -->
<ComboBox Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Top"
ItemsSource="{Binding LanguageList, Mode=TwoWay}"
SelectedItem="{Binding SelectLanguage, Mode=TwoWay}"
SelectionChanged="ComboBox_SelectionChanged"/>
<!-- Button 클릭 시 언어 변경 -->
<Button Name="MyButton" Content="{DynamicResource EXPLAIN_01}"
Command="{Binding SwitchLanguage_ClickCommand}"
HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,0,0"/>
<!-- DynamicResource를 사용하여 TextBlock에 텍스트 표시 -->
<TextBlock Text="{DynamicResource EXPLAIN_01}" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
<TextBlock Text="{DynamicResource EXPLAIN_02}" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
</Grid>
</Window>
4. ViewModel 설정
ViewModel
에서는 ComboBox
로 선택된 언어에 따라 ResourceDictionary
를 갱신합니다. ResetLanguage
메서드는 선택된 언어에 맞는 리소스를 불러와 UI를 업데이트합니다. (code pro플러그인에서 json 양식이 맞지 않는 오류가 생겨 임시적으로 viewmodel만 설정 다르게 함.)
- ViewModel.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Input;
namespace test241106_ResouceDictionary
{
public class ViewModel : INotifyPropertyChanged
{
public string SelectLanguage { get; set; }
public ObservableCollection LanguageList { get; set; }
public ICommand SwitchLanguage_ClickCommand => new RelayCommand(SwitchLanguage_Click);
public ViewModel()
{
LanguageList = new ObservableCollection { "en-us", "ko-kr", "es-eu", "ja-jp" };
SelectLanguage = CultureInfo.CurrentCulture.Name;
ResetLanguage();
}
public void SwitchLanguage_Click()
{
ResetLanguage();
}
public void ComboBoxEdit_EditValueChanged()
{
ResetLanguage();
}
private void ResetLanguage()
{
// 프로젝트 루트 디렉터리에서 리소스 파일을 가져옴
string projectDirectory = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory)?.Parent?.Parent?.FullName;
string dictionaryPath = Path.Combine(projectDirectory, $"ResourceDictionary.{SelectLanguage}.xaml");
Application.Current.Resources.MergedDictionaries.Clear();
if (File.Exists(dictionaryPath))
{
var newDictionary = new ResourceDictionary { Source = new Uri(dictionaryPath, UriKind.RelativeOrAbsolute) };
Application.Current.Resources.MergedDictionaries.Add(newDictionary);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class RelayCommand : ICommand
{
private readonly Action _execute;
public RelayCommand(Action execute) => _execute = execute;
public bool CanExecute(object parameter) => true;
public void Execute(object parameter) => _execute();
public event EventHandler CanExecuteChanged;
}
}
5. MainWindow.xaml.cs에서 언어 변경 이벤트 설정
ComboBox
에서 언어를 선택하면 SelectionChanged
이벤트가 발생하여 ResetLanguage
메서드를 호출합니다.
- MainWindow.xaml.cs
using System.Windows;
namespace test241106_ResouceDictionary
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
private void ComboBox_SelectionChanged(object sender, RoutedEventArgs e)
{
((ViewModel)DataContext).ComboBoxEdit_EditValueChanged();
}
}
}
동작 설명
- 앱 실행 시 초기 언어 설정:
App.xaml
에서ResourceDictionary.ko-KR.xaml
이 기본으로 로드됩니다. 따라서 앱이 처음 실행될 때는 한국어가 기본 언어로 설정됩니다. - 언어 선택:
ComboBox
에서 언어를 선택하면ComboBox_SelectionChanged
이벤트가 발생하여ComboBoxEdit_EditValueChanged
메서드를 호출하고, 이 메서드는ResetLanguage
를 실행합니다. - 리소스 갱신:
ResetLanguage
는 선택된 언어에 해당하는ResourceDictionary
파일을 찾아 로드하고, UI는DynamicResource
를 통해 자동으로 해당 언어로 업데이트됩니다.