我想通过button_click事件更改我的项目语言,所以我使用ResourceDictionary来这样做:
XAML
<Button Content="{DynamicResource LanguageSetting}" Click="btn_LanguageSetting_Click"/>
代码隐藏
public static string windowCurrentLanguageFile = "Language/en.xaml";
private void btn_LanguageSetting_Click(object sender, RoutedEventArgs e)
{
windowCurrentLanguageFile = windowCurrentLanguageFile == "Language/en.xaml"
? "Language/fr.xaml"
: "Language/en.xaml";
var rd = new ResourceDictionary() { Source = new Uri(windowCurrentLanguageFile, UriKind.RelativeOrAbsolute) };
if (this.Resources.MergedDictionaries.Count == 0)
this.Resources.MergedDictionaries.Add(rd);
else
this.Resources.MergedDictionaries[0] = rd;
}
这对于 xaml 文件效果很好,但我也想在后面的代码中更改 View 模型的语言。
xaml 中的我的 ItemsControl:
<ItemsControl ItemsSource="{Binding ItemOperate}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type viewmodel:SelectableViewModel}">
<Border x:Name="Border" Padding="0,8,0,8" BorderThickness="0 0 0 1" BorderBrush="{DynamicResource MaterialDesignDivider}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Checkerz" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ToggleButton VerticalAlignment="Center" IsChecked="{Binding IsSelected}"
Style="{StaticResource MaterialDesignActionLightToggleButton}"
Content="{Binding Code}" />
<StackPanel Margin="8 0 0 0" Grid.Column="7">
<TextBlock FontWeight="Bold" Text="{Binding Name}" />
<TextBlock Text="{Binding Description}" />
</StackPanel>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="Border" Property="Background" Value="{DynamicResource MaterialDesignSelection}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
与 ViewModel 的绑定(bind)如下:
public class SelectableViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected == value) return;
_isSelected = value;
OnPropertyChanged();
}
}
private char _code;
public char Code
{
get { return _code; }
set
{
if (_code == value) return;
_code = value;
OnPropertyChanged();
}
}
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value) return;
_name = value;
OnPropertyChanged();
}
}
private string _description;
public string Description
{
get { return _description; }
set
{
if (_description == value) return;
_description = value;
OnPropertyChanged();
}
}
}
和
public MainViewModel()
{
_itemOperate = CreateData();
}
private static ObservableCollection<SelectableViewModel> CreateData()
{
return new ObservableCollection<SelectableViewModel>
{
new SelectableViewModel
{
Code = 'E',
Name = "Erase",
Description = "Erase The MCU Chip By Page"
},
new SelectableViewModel
{
Code = 'D',
Name = "Detect",
Description = "Detect The MCU Flash",
},
new SelectableViewModel
{
Code = 'P',
Name = "Programming",
Description = "Programming The MCU Chip By Hex File",
},
new SelectableViewModel
{
Code = 'V',
Name = "Verify",
Description = "Verify The Downing Code",
},
new SelectableViewModel
{
Code ='L',
Name = "Lock",
Description = "Lock The Code To Protect The MCU",
}
};
}
那么我该如何更改模型 SelectableViewModel Code
、Name
、Description
的语言而不是使用此硬代码呢?谢谢!
最佳答案
我将向您建议一个在运行时更改语言的解决方案。
创建资源管理器:
public class CultureResources { private static bool isAvailableCulture; private static readonly List<CultureInfo> SupportedCultures = new List<CultureInfo>(); private static ObjectDataProvider provider; public CultureResources() { GetAvailableCultures(); } /// <summary> /// Gets automatically all supported cultures resource files. /// </summary> public void GetAvailableCultures() { if (!isAvailableCulture) { var appStartupPath = AppDomain.CurrentDomain.BaseDirectory; foreach (string dir in Directory.GetDirectories(appStartupPath)) { try { DirectoryInfo dirinfo = new DirectoryInfo(dir); var culture = CultureInfo.GetCultureInfo(dirinfo.Name); SupportedCultures.Add(culture); } catch (ArgumentException) { } } isAvailableCulture = true; } } /// <summary> /// Retrieves the current resources based on the current culture info /// </summary> /// <returns></returns> public Resources GetResourceInstance() { return new Resources(); } /// <summary> /// Gets the ObjectDataProvider wrapped with the current culture resource, to update all localized UIElements by calling ObjectDataProvider.Refresh() /// </summary> public static ObjectDataProvider ResourceProvider { get { return provider ?? (provider = (ObjectDataProvider)System.Windows.Application.Current.FindResource("Resources")); } } /// <summary> /// Changes the culture /// </summary> /// <param name="culture"></param> public void ChangeCulture(CultureInfo culture) { if (SupportedCultures.Contains(culture)) { Resources.Culture = culture; ResourceProvider.Refresh(); } else { var ci = new CultureInfo("en"); Resources.Culture = ci; ResourceProvider.Refresh(); } } /// <summary> /// Sets english as default language /// </summary> public void SetDefaultCulture() { CultureInfo ci = new CultureInfo("en"); Resources.Culture = ci; ResourceProvider.Refresh(); } /// <summary> /// Returns localized resource specified by the key /// </summary> /// <param name="key">The key in the resources</param> /// <returns></returns> public static string GetValue(string key) { if (key == null) throw new ArgumentNullException(); return Resources.ResourceManager.GetString(key, Resources.Culture); } /// <summary> /// Sets the new culture /// </summary> /// <param name="cultureInfo"> new CultureInfo("de-DE"); new CultureInfo("en-gb");</param> public void SetCulture(CultureInfo cultureInfo) { //get language short format - {de} {en} var ci = new CultureInfo(cultureInfo.Name.Substring(0,2)); ChangeCulture(ci); Thread.CurrentThread.CurrentCulture = cultureInfo; Thread.CurrentThread.CurrentUICulture = cultureInfo; // CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-GB"); } }
根据需要为每种语言类型定义资源文件。 上面我已经定义了英语的默认值和德语的第二个文件(您可以看到“.de”扩展名。对于任何其他语言也是如此。 确保打开 Resources.resx 属性并选择值 PublicResXFileCodeGenerator 作为自定义工具。为了通过对象提供者公开资源,此步骤是必要的。
用法: 在 Xaml 中:
Text="{Binding ResourcesText1, Source={StaticResource Resources}}"
来自 *.cs:Resources.ResourcesText1。
附注 当您更改区域性时,请确保从 CultureResouces 中调用 SetCulture 方法。
关于c# - 如何在运行时使用资源字典更改 UI 语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45407108/