【问题标题】:WPF UI is not updating on change of ConcurrentBag type collectionWPF UI 不更新 ConcurrentBag 类型集合的更改
【发布时间】:2012-01-15 09:16:48
【问题描述】:

我有一个绑定到 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);
    }
}

【问题讨论】:

    标签: c# wpf binding concurrent-collections


    【解决方案1】:

    我认为上一个答案不会为您的问题提供解决方案。实际上,您根本没有更新集合:您正在更新集合中所有 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));
    
       }
    }
    

    【讨论】:

    • +1,我误读了这个问题,因为“=”在我的脑海中听起来像“==”。
    【解决方案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));
    

    【讨论】:

    • 意思是,我每次都需要创建一个新的集合对象?我也试过这个,但它甚至不工作..
    猜你喜欢
    • 1970-01-01
    • 2013-11-03
    • 2015-01-11
    • 2012-11-27
    • 2021-11-04
    • 2014-01-17
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    相关资源
    最近更新 更多