2012-01-15 18 views
2

WPF UIのDataGridにバインドされたコレクションがあります。ConcurrentBag型コレクションの変更時にWPF UIが更新されない

私の要件は、コレクションのすべてのアイテムに対して1秒間に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

私は前の回答があなたの問題を解決するとは思わないと思います。実際にはコレクションはまったく更新されていません。コレクション内のすべてのストックインスタンスのプロパティを更新しています。コレクションを更新するとは、アイテムを追加または削除することを意味します。セマンティクスが異なるため、バインドされたコントロールは、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

2

EDIT:私はプロパティの更新ではなく、コレクションの更新については、実際には、あなたの質問を読み違えます。 Priceプロパティのコレクションのすべてのアイテムを実際に更新したい場合、下の例のWhere節は当然あなたを助けません。


あなたが実際にあなたのコレクションを変更していない;)

stockCollection.ToList().ForEach((s) => s.Price = DateTime.Now.Millisecond); 
あなたがやりたいかもしれません

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

EDIT

手段を、I新しいcollectioを作成する必要があります毎回オブジェクト?

あなたのコレクションには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)); 
+0

私は毎回新しいコレクションオブジェクトを作成する必要がありますか?私もこれを試してみましたが、うまくいきませんでした。 –

+0

更新された回答を見てください – ken2k

関連する問題