2012-01-15 89 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