2012-01-15 82 views
2

我有WPF UI中绑定到datagrid的集合。WPF UI不会更新ConcurrentBag类型集合的更改

我的要求就像我必须为集合中的每个项目每秒更新一次属性的值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); 
    } 
} 

回答

4

我不认为以前的答案会为您的问题提供解决方案。您实际上并未完全更新集合:您正在更新集合中所有Stock实例的属性。更新收集意味着添加或删除其中的项目。由于语义不同,当您触发CollectionChanged事件时,绑定控件可能不会检查集合中已有对象的属性。这将是一个明智的优化。

我建议你在你的Stock类中实现INotifyPropertyChange,然后在Price属性设置器中在这里触发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)); 

    } 
} 
+0

+1,我误解了这个问题,因为'='在我脑海中听起来像'=='。 – ken2k 2012-01-15 10:00:33

2

编辑:我误解你的问题是实际上有关属性更新,而不是一个集合更新。 因此,如果您实际上想更新Price属性中的所有项目,那么下面示例中的Where子句不会对您有所帮助。


你实际上不修改您的收藏;)

stockCollection.ToList().ForEach((s) => s.Price = DateTime.Now.Millisecond); 

你可能想要做的:

stockCollection = new ConcurrentBag(stockCollection.Where(...)); 

编辑

手段,我需要创建一个新的收藏每次都有对象?

由于您的收藏不实施INotifyCollectionChangedINotifyPropertyChanged,是的。 如果可能,我建议使用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)); 
+0

手段,我需要每次创建一个新的集合对象?我也尝试过这一个,但它甚至没有工作。 – 2012-01-15 09:31:49

+0

查看更新的答案 – ken2k 2012-01-15 09:43:35