【发布时间】:2021-05-20 03:59:56
【问题描述】:
我有一个ListView 绑定到一个集合,我希望ListView 在一个项目添加到集合时自动更新。我设法使用ObservableCollection 让它工作,但我宁愿使用INotifyPropertyChanged。也许你可以给我一个提示我做错了什么?
首先,这是 XAML 的(相关部分):
<StackPanel DataContext="{Binding Family}"> <!-- DataContext is of type Family -->
<TextBlock Text="{Binding LastName}"/>
<ListView ItemsSource="{Binding Members}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding FirstName}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
以下是相关类:
public class Family : INotifyPropertyChanged
{
public string LastName { get; private set; }
private readonly IList<Member> _members;
public IEnumerable<Member> Members { get => _members; }
public Family(string lastName, IEnumerable<Member> members)
{
LastName = lastName;
_members = members.ToList();
}
public void AddMember(string name)
{
var member = new Member { FirstName = name };
_members.Add(member);
OnPropertyChanged(nameof(Members));
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
public class Member
{
public string FirstName { get; set; }
}
如果我使用此代码并在某处调用 AddMember,它将不会更新 ListView GUI。我不明白为什么不这样做,因为AddMember 调用OnPropertyChanged(nameof(Members)),而Members 是ListView 所绑定的。所以它应该会收到有关更改的通知。
那我做错了什么?
如果我相应地将IList<Member> _members 更改为ObservableCollection<Member> _members 并将_members = members.ToList() 更改为_members = new ObservableCollection<Member>(members),它会按预期工作。
【问题讨论】:
-
“它应该收到有关更改的通知” - 它收到通知,然后比较当前值和以前的值,发现它们相等并且什么都不做。你可以在你的类中实现 INotifyCollectionChanged。仅添加一项后重建所有项目可能会很昂贵
-
@ASh 你能指出一些链接来解释你的暗示(或解释你自己)吗?关于该比较:比较什么以及何时比较?为什么先前值和当前值相等? (当然它们在引用方面是相同的,但内容发生了变化。)重构所有项目是什么意思?
-
在通知
Members属性后,比较ItemsSource 的当前值和Members 的新值。它们是对 _members 列表的相同引用。收藏内容无所谓 -
分配新的Itemssource时,ListView会删除所有项目,然后为新集合的元素创建新项目(重构)
-
当您对 ObservableCollection 说“它按预期工作”时,为什么不坚持使用这种标准方法呢?这是您通常会做的事情。其他的一切看起来都很尴尬。
标签: c# wpf observablecollection inotifypropertychanged