c# - 为什么 List<T> 属性的通知不起作用

标签 c# wpf mvvm inotifypropertychanged

为什么上涨INotifypPropertyChanged对于 List<T>属性不起作用?

考虑这个 MCVE:

public class NotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string property = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}

public class TextWrapper
{
    public string Text { get; set; }
    public override string ToString() => Text;
}

public class ViewModel : NotifyPropertyChanged
{
    public List<string> List { get; } = new List<string>();
    public TextWrapper Text { get; } = new TextWrapper();

    public void AddToList(string text)
    {
        List.Add(text);
        OnPropertyChanged(nameof(List));
    }

    public void ChangeText(string text)
    {
        Text.Text = text;
        OnPropertyChanged(nameof(Text));
    }
}

public partial class MainWindow : Window
{
    readonly ViewModel _vm = new ViewModel();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = _vm;
    }
}

xaml:

<TextBlock Text="{Binding Text}" />
<ListBox ItemsSource="{Binding List}" />

调用 _vm.ChangeText(...)将正确更新TextBlock , 同时调用 _vm.AddToList(...)不更新 ListBox (它将保持为空)。为什么?

请注意:我知道 ObservableCollection<T>我知道两种可能的解决方法(将 setter 添加到 List 并将其设置为例如 null 然后返回或更改 DataContext/ItemsSource )。我只是好奇屋檐下的东西是什么List<T>TextWrapper 更特别.

最佳答案

当 WPF 绑定(bind)处理 PropertyChanged 事件时,它不会更新其目标属性,除非它产生的有效值实际发生了变化。

因此,除非 List 属性值实际发生变化(添加元素时它不会发生变化),否则调用

OnPropertyChanged(nameof(List));

没有效果。

替换

public List<string> List { get; } = new List<string>();

public ObservableCollection<string> List { get; } = new ObservableCollection<string>();

然后像这样编写 AddToList 方法:

public void AddToList(string text)
{
    List.Add(text);
}

对于您的 TextWrapper 类:由于您直接绑定(bind)到 TextWrapper 实例,因此 Binding 会调用其覆盖的 ToString() 方法,因此每当 TextWrapper 的 Text 时都会产生不同的值属性已更改。

关于c# - 为什么 List<T> 属性的通知不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43843174/

相关文章:

c# - 使用 T4 自定义一些自动生成的代码

c# - 自动重启windows服务

c# - 为我的电子调查应用程序创建一个 .csv 文件。我该如何开始?

wpf - MVVM - 绑定(bind)和更新方法

wpf - 我应该在哪里放置 UserControls 列表而不破坏 MVVM?

c# - 编写 Windows Web 服务但不确定使用哪种语言?

c# - 在 C# 服务器上管理连接的 android 客户端

c# - 面向组件的设计 : Problems with dependencies in dialogs

wpf - 如何将某些 WPF 列表框设置为单选按钮?

mvvm - 使用 MVVM 模式打印 WPF 视觉效果