ObservableCollection未通知更新(MVVM WPF GridView)
本文关键字:WPF GridView MVVM 通知 更新 ObservableCollection | 更新日期: 2023-09-27 18:12:54
我有一个GridView问题,它由"People"填充
ObservableCollection<Person> People
{
get { return directory.People }
set { directory.People = value; }
}
这是对GridView的完美更新,但我只想显示名称为"Andy"的人,所以我将其更改为以下内容:
ObservableCollection<Person> People
{
get {
var andys = new ObservableCollection<Person>();
foreach (var person in directory.People)
{
if (person.Name == "Andy")
{
andys.Add(person);
}
}
return andys;
}
set { directory.People = value; }
}
上面的代码将完美地填充GridView,但如果我执行以下,它不会更新它
Private Void AddAndy()
{
directory.People.Add(new Person{ name = Andy2 });
//People.Add(new Person { name = Andy2 }); -- Doesn't work either
}
这意味着,尽管GridView最初会填充,但任何其他更改都不会对网格产生影响。我已经切换回直接查看Directory.People,并在添加人员时返回更新。
我已经检查过,当我把这个人添加到"dirctory.People"时,它确实表明列表中有一个新项目。
我能做些什么来迫使"People"变量认识到有变化,进而更新GridView吗?
提前感谢
Andy
那么XAML框架是如何知道directory.People
集合何时更新的呢?
我建议使用ListCollectionView,并将其作为ViewModel、上的属性公开
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class PeoplesViewModel
{
private ObservableCollection<Person> _people;
private ListCollectionView _filteredPeople;
public PeoplesViewModel()
{
_people = new ObservableCollection<Person>();
_filteredPeople = new ListCollectionView(_people);
_people.Add(new Person { FirstName = "John", LastName = "Smith" });
_people.Add(new Person { FirstName = "David", LastName = "Smith" });
_people.Add(new Person { FirstName = "John", LastName = "Jones" });
_filteredPeople.Filter = x => ((Person) x).FirstName == "John";
}
public IEnumerable People { get { return _filteredPeople; } }
}
现在,当一个新的人员添加到视图时,将自动更新。
现在我意识到这与上面略有不同,但如果是目录。人是ObservableCollection<T>
,那么这应该起作用。
我认为最好的解决方案是为过滤后的结果创建一个属性。
public ICollection<People> FilteredPeople
{
get
{
return this._FilteredPeople;
}
set
{
if (value != null && !value.Equals(this._FilteredPeople))
{
this._FilteredPeople = value;
this.OnPropertyChanged("FilteredPeople");
}
}
}
实现INotifyPropertyChanged
/// <summary>
/// Triggered when a class property value is changed
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Helper for PropertyChanged event
/// </summary>
/// <param name="propertyName">Name of the property</param>
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
然后将事件处理程序添加到可观察集合CollectionChanged事件中。在该处理程序中,将集合属性设置为筛选结果。绑定到FilteredPeople属性即可离开。您可以很容易地将其扩展为参数化所使用的名称。
这将导致控件的完全重绘,而不仅仅是添加元素,因此,如果您的集合达到高计数,请注意这一点。