由於本示例基於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>