下午好,我正在使用 wpf、.net 8.0 框架、mvvm 社区工具包进行运行时全球化。我设法在没有工具包的情况下做到了这一点(INotifyPropertyChanged,#commented code),但我无法切换到 ObservableObject 方式,有人可以帮助我吗,tqvm。
MainWindow1.xaml
<Window x:Class="MvvmTutorials.ToolkitIntro.Views.MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:MvvmTutorials.ToolkitIntro"
xmlns:local="clr-namespace:MvvmTutorials.ToolkitIntro.Views"
mc:Ignorable="d"
Title="MainWindow1" Height="450" Width="800">
<Window.DataContext>
<vm:LanguageManager />
</Window.DataContext>
<StackPanel HorizontalAlignment="Center">
<!--<ComboBox x:Name="LanguageList" SelectedIndex="0" Margin="10" SelectionChanged="LanguageList_SelectionChanged" />-->
<ComboBox ItemsSource="{Binding Langs}" SelectedItem="{Binding LangItem}" Margin="10" />
<TextBlock FontSize="20" Margin="10" Text="{Binding [String1],Source={x:Static vm:LanguageManager.InstanceF}}" />
<TextBox FontSize="20" Margin="10" Text="{Binding [String2],Source={x:Static vm:LanguageManager.InstanceF},Mode=OneWay}" />
<Button FontSize="20" Margin="10" Content="{Binding [String3],Source={x:Static vm:LanguageManager.InstanceF}}" />
</StackPanel>
</Window>
MainWindow1.xaml.cs
namespace MvvmTutorials.ToolkitIntro.Views;
/// <summary>
/// Interaction logic for MainWindow1.xaml
/// </summary>
public partial class MainWindow1 : Window
{
public MainWindow1()
{
InitializeComponent();
//LanguageList.ItemsSource = new List<string>
//{
// "en-US",
// "ja",
//};
}
//private void LanguageList_SelectionChanged(object sender, SelectionChangedEventArgs e)
//{
// LanguageManager.InstanceF.ChangeLanguage(new CultureInfo((sender as ComboBox).SelectedItem.ToString()));
//}
}
语言管理器.cs
namespace MvvmTutorials.ToolkitIntro;
//public partial class LanguageManager : INotifyPropertyChanged
public partial class LanguageManager : ObservableObject
{
[ObservableProperty]
private List<string> _langs = new List<string>()
{
"en-US",
"ja",
"zh-CN",
};
[ObservableProperty]
private string _langItem = "en-US";
partial void OnLangItemChanged(string value)
{
CultureInfo cultureInfo = new CultureInfo(value);
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
//MessageBox.Show(this["String1"]);
}
private static readonly Lazy<LanguageManager> _lazyZ = new Lazy<LanguageManager>(() => new LanguageManager());
public static LanguageManager InstanceF => _lazyZ.Value;
private readonly ResourceManager _resourceManagerS;
public LanguageManager()
{
_resourceManagerS = new ResourceManager("MvvmTutorials.ToolkitIntro.Resources.Lang1", typeof(LanguageManager).Assembly);
}
public string this[string name]
{
get
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
return _resourceManagerS.GetString(name);
}
}
//public event PropertyChangedEventHandler? PropertyChanged;
//public void ChangeLanguage(CultureInfo cultureInfo)
//{
// CultureInfo.CurrentCulture = cultureInfo;
// CultureInfo.CurrentUICulture = cultureInfo;
// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("item[]"));
//}
}
我希望全球化能够以 ObservableObject 的方式工作。但是,我不知道如何切换 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("item[]"));以 ObservableObject 方式(MVVM 社区工具包)。
请参阅使用索引器中的以下注释:
声明索引器将自动在对象上生成一个名为
的属性。Item
属性无法从实例成员访问表达式直接访问。此外,如果您将自己的Item
属性添加到带有索引器的对象,您将收到 CS0102 编译器错误。为了避免此错误,请使用 IndexerNameAttribute 重命名索引器,如下所述。Item
这意味着您不能同时声明一个(默认命名的)索引器和一个名为
Item
的 ObservableProperty:
public partial class ViewModel : ObservableObject
{
[ObservableProperty]
private string[] item;
public string this[string key] => "something"; // CS0102 here
}
在您的情况下,拥有附加属性似乎根本没有用,因为您始终可以简单地使用 ObservableObject 的
OnPropertyChanged
方法:
public void ChangeLanguage(CultureInfo cultureInfo)
{
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
OnPropertyChanged("Item[]");
}