为什么上升INotifypPropertyChanged
为List<T>
属性不起作用?为什么通知列表<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>
,我知道大约两个可能的解决方法(添加二传手到List
并将其设置为例如null
先升后回或更换DataContext
/ItemsSource
)。我只是好奇什么在屋顶下使List<T>
比TextWrapper
更特别。
附注 - 不确定是否可能导致问题,但List是保留名称。尝试改变它或用“@”作为前缀,如“@ List”。 –
@KamilSolecki用某个类的名字命名一个属性是完全合法的。还要注意''List'是一个_generic_类,所以它的名字从来就不是简单的“List”,而是“List'1”等。 –