2

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);
    }
}
4

2 に答える 2

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));

   }
}
于 2012-01-15T09:54:08.193 に答える
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));
于 2012-01-15T09:21:17.090 に答える