由于本示例基于MVVMLightToolkit,所以我们的ViewModel基类继承自MVVMLightToolkit提供的ViewModelBase,并命名为AdvancedViewModelBase,项目中所有的ViewModel都继承自这个类,先看类图:
由于本示例基于MVVMLightToolkit,所以我们的ViewModel基类继承自MVVMLightToolkit提供的ViewModelBase,并命名为AdvancedViewModelBase,项目中所有的ViewModel都继承自这个类。
本文的重点是“实时”切换。我们知道,ViewModel中的属性发生变化时如果要将变化反映到界面中则必将使用通知机制—INotifyPropertyChanged,因此我们引入了一个中间“代理”类ObservableResources,代码如下:
public class ObservableResources : INotifyPropertyChanged { public string this[string resourceName] { get { return Language.ResourceManager.GetString(resourceName); } } public event PropertyChangedEventHandler PropertyChanged; public void UpdateBindings() { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item[]")); } }
注意,因为我们使用了类的索引器,所以PropertyChangedEventArgs的参数应该为“Item[]”,Language类为资源文件自动生成。
之后,我们在AdvancedViewModelBase类中对其进行实例化。AdvancedViewModelBase的关键代码如下:
public ObservableResources LanguageResource { get; set; } public ICommand ChangeLanguageCommand { get; set; } public AdvancedViewModelBase() { LanguageResource = new ObservableResources(); ChangeLanguageCommand = new RelayCommand<EdsLanguage>(ChangeLanguage); } private void ChangeLanguage(EdsLanguage lang) { var culture = new CultureInfo(lang.CultureName); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; LanguageResource.UpdateBindings(); }
这里我们准备了一个ICommand以供在界面中进行绑定,当ChangeLanguageCommand被激活时执行ChangeLanguage方法(传递选定的语言类型),调用LanguageResource的UpdateBindings方法通知界面当前Culture的改变。
EdsLanguage类为自定义,定义了Culture、图标及语言信息。
在XAML中,需要使用多语言的部分则需如此调用
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding LanguageResource[Login_UserNameLabel]}" />
其中Login_UserNameLabel则为资源文件中的Name。
改变语言类型的示例(本例使用了EventToCommand,当然用其他方式也可):
<ComboBox SelectedItem="{Binding SelectedLanguage}" ItemsSource="{Binding EdsLangList}" x:Name="cbLanguage" Width="110" Height="30" HorizontalAlignment="Left"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <cmd:EventToCommand Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding ElementName=cbLanguage,Path=SelectedItem}"/> </i:EventTrigger> </i:Interaction.Triggers> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Width="28" Height="28" Source="{Binding FlagIcon}"/> <TextBlock Text="{Binding LanguageName}" VerticalAlignment="Center"/> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>