我想通过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文件,但我也想在后面的代码中更改我的viewmodel语言。
我在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 ,如下所示:
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
而不是使用此硬代码?谢谢!
答案 0 :(得分:3)
我将为您提供一种在运行时更改语言的解决方案。
创建资源管理器:
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 。
P.S。 更改文化时,请务必从 CultureResouces 中调用 SetCulture 方法。