ObservableCollection在I“;新的“;它
本文关键字:新的 ObservableCollection | 更新日期: 2023-09-27 17:58:30
我的UI上有一个ListBox,它绑定到ObservableCollection的一个属性。我在视图模型的构造函数中的属性中设置了一个ObservableCollection的新实例,我可以通过表单上的按钮向其添加项。这些项在列表中可见。
一切都很好。
但是,如果我在按钮回调中使用new重新初始化属性,它会破坏绑定,UI将不再显示集合中的内容。
我假设绑定会继续查找属性的值,但它可能链接到一个被new破坏的引用。
我说对了吗?有人能详细介绍一下这是如何联系起来的吗?当我的视图模型不了解视图时,有没有办法重新绑定它?
请确保在重新初始化集合后引发PropertyChangedEvent。引发此事件将允许视图在模型不了解视图的情况下处理对属性的更改。
class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
private ObservableCollection<string> _list = new ObservableCollection<string>();
public ObservableCollection<string> List
{
get { return _list; }
set
{
_list = value;
NotifyPropertyChanged("List");
}
}
public Model()
{
List.Add("why");
List.Add("not");
List.Add("these?");
}
}
根据您的描述,我认为您需要重构公开ObservableCollection的属性,以便在为其分配新值时也引发PropertyChanged事件。示例:
public ObservableCollection<int> Integers
{
get { return this.integers; }
set {
if (this.integers != value)
{
this.integers = value;
RaisePropertyChanged("Integers");
}
}
}
假设您已经在ViewModel上实现了INotifyPropertyChanged,那么每当您为其分配新值时,都可以在ObservableCollection上引发属性更改事件。
public ObservableCollection<string> MyList { get; set; }
public void SomeMethod()
{
MyList = new ObservableCollection<string>();
RaisePropertyChanged("MyList");
}
对ObservableCollection
的更新是通过挂接到CollectionChanged
事件来处理的,因此当您创建新的ObservableCollection
时,您的观察者仍在查看旧集合。
两个简单的建议是在包含ObservableCollection
的类上实现INotifyPropertyChanged
,并在collection属性的setter中引发PropertyChanged
事件(如果是您自己的代码,请不要忘记先在您的观察者中从旧事件中取消挂钩)。
private ObservableCollection<string> _myCollection = new ObservableCollection<string>();
public ObservableCollection<string> MyCollection
{
get { return _myCollection; }
set
{
if(_myCollection == value)
return;
_myCollection = value;
RaisePropertyChanged("MyCollection");
}
}
第二种,也是我通常更喜欢的选择是,当新数据到达时,只需清除并用新数据重新填充集合。
public void HandleCollectionData(IEnumerable<string> incomingData)
{
MyCollection.Clear();
foreach(var item in incomingData)
{
MyCollection.Add(item);
}
}