我有一个集合,它绑定到WPF UI中的数据网格。
我的要求是,我必须为集合中的每个项目每秒更新属性的值10次。
所以我采用了ConcurrentBag类型的集合。更新每个项目的值之后。我正在显式启动RaisePropertyChange。但是UI并没有改变。
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (stockCollection != null)
{
stockCollection.ToList().ForEach((s) => s.Price = DateTime.Now.Millisecond);
Action raiseStockCollectionProperty = new Action(() => RaisePropertyChangedEvent("StockCollection"));
Dispatcher.BeginInvoke(raiseStockCollectionProperty);
}
}
我认为前面的答案不会为您的问题提供解决方案。事实上,您根本没有更新集合:您正在更新集合中所有Stock实例的属性。更新集合意味着添加或删除其中的项。由于语义不同,当您触发CollectionChanged事件时,绑定控件可能不会检查集合中现有对象的属性。这将是一个合理的优化。
我建议您在Stock类中实现INotifyPropertyChange,并在Price属性setter中在此处激发propertyChanged事件(不过,在好的线程上,使用Dispatcher)。
private DateTime _price;
public DateTime Price
{
get
{
return _price;
}
set
{
if(_price!=value)
{
_price = value;
RaisePropertyChanged("Price");
}
}
}
protected void RaisePropertyChanged(string property)
{
var propertyChanged = PropertyChanged;
if(propertyChanged!=null)
{
propertyChanged(this,new PropertyChangedEventArgs(property));
}
}
EDIT:我误解了您的问题,实际上是关于属性更新,而不是集合更新。因此,如果您真的想更新集合中所有项的Price
属性,那么下面示例中的Where
子句当然对您没有帮助。
你实际上并没有修改你的收藏;)
stockCollection.ToList().ForEach((s) => s.Price = DateTime.Now.Millisecond);
你可能想做:
stockCollection = new ConcurrentBag(stockCollection.Where(...));
编辑:
意思是,我每次都需要创建一个新的集合对象?
由于您的集合既没有实现INotifyCollectionChanged
,也没有实现INotifyPropertyChanged
,所以是的。如果可能的话,我建议使用ObservableCollection
而不是您当前的收藏类型。ObservableCollection
能够通知项目属性的更新,并在添加/删除项目时引发事件。
ObservableCollection<YourType> myCollection = new ObservableCollection<YourType>();
...
public ObservableCollection<YourType> MyCollection
{
get
{
return this.myCollection;
}
set
{
if (value != this.myCollection)
{
this.myCollection = value;
this.RaisePropertyChanged("MyCollection");
}
}
}
...
// Following lines of code will update the UI because of INotifyCollectionChanged implementation
this.MyCollection.Remove(...)
this.MyCollection.Add(...)
// Following line of code also updates the UI cause of RaisePropertyChanged
this.MyCollection = new ObservableCollection<YourType>(this.MyCollection.Where(z => z.Price == 45));