从 INotifyPropertyChanged 切换到 ObservableObject

问题描述 投票:0回答:1

下午好,我正在使用 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 社区工具包)。

c# wpf globalization observableobject community-toolkit-mvvm
1个回答
0
投票

请参阅使用索引器中的以下注释:

声明索引器将自动在对象上生成一个名为

Item
的属性。
Item
属性无法从实例成员访问表达式直接访问。此外,如果您将自己的
Item
属性添加到带有索引器的对象,您将收到 CS0102 编译器错误。为了避免此错误,请使用 IndexerNameAttribute 重命名索引器,如下所述。

这意味着您不能同时声明一个(默认命名的)索引器和一个名为

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[]");
}
© www.soinside.com 2019 - 2024. All rights reserved.