30987

Calculation on a realtime changing collection ( in c#)

Question:

I have a changing collection of changing objects(add/delete in Collection as well as property changes are also possible).

I want to get a new collection by some calculation on this Collection (summation / multiplication over some fields of all the objects having same value of a field). And bind calculated list to UI.

for Ex: So I have a list of rate and qty of different qualities of several fruits and now I want to find a new list having avg rate and total quantity of each fruit(irrespective of quality) given that rate & quantity can be changes at run time as well as some more qualities and fruit-species can be added to collection.

<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/FS15G.jpg" data-original="https://i.stack.imgur.com/FS15G.jpg" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

Now If rates or quantity changes at runtime in first List changes should be reflected in second list also. <img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/5wzfP.jpg" data-original="https://i.stack.imgur.com/5wzfP.jpg" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

Please suggest which methods should be used to achieve it considering we are binding the list to a Datagrid.

Answer1:

There is a neat Reactive Extension called Buffer:

var o = new ObservableCollection<long>(); var s1 = Observable.Interval(TimeSpan.FromMilliseconds(100)).Subscribe(o.Add); var s2 = Observable.FromEventPattern<NotifyCollectionChangedEventArgs>(o, "CollectionChanged") .Buffer(TimeSpan.FromMilliseconds(500)) .Subscribe( s => { Console.WriteLine("Last received {0}. Current count: {1}", Convert.ToInt64(s.Last().EventArgs.NewItems[0]), o.Count); });

This will allow you to receive on collection changed events as they occur, but ignore all except the last one.

<strong>UPDATE 1</strong>

It is a known issue that CollectionChanged does not fire when items are updated. The MSDN documentation is simply incorrect. You will have to implement a TrulyObservableCollection but your data elements must implement INotifyChanged interface as well.

namespace ConsoleApplication1 { #region using System; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Reactive.Linq; using System.Threading; #endregion internal class Program { #region Methods private static void Main(string[] args) { var autoReset = new AutoResetEvent(false); var r = new Random(); var o = new TrulyObservableCollection<DataPoint>(); var subscription1 = Observable.Interval(TimeSpan.FromSeconds(1)).Take(3).Subscribe( i => { o.Add( new DataPoint { ItemCount = r.Next(100) }); Console.WriteLine("Fire1 {0}", i); }); var subscription2 = Observable.FromEventPattern<NotifyCollectionChangedEventArgs>(o, "CollectionChanged") .Subscribe(s => { Console.WriteLine("List changed. Current total {0}", o.Sum(s1 => s1.ItemCount)); }); var subscription3 = Observable.Interval(TimeSpan.FromSeconds(1)).Delay(TimeSpan.FromSeconds(3)).Take(3).Finally( () => { o.Clear(); autoReset.Set(); }).Subscribe( i => { if (o.Any()) { o[r.Next(o.Count)].ItemCount = r.Next(100); Console.WriteLine("Fire3 {0}", i); } }); autoReset.WaitOne(); } #endregion public class TrulyObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged { #region Constructors and Destructors public TrulyObservableCollection() { CollectionChanged += this.TrulyObservableCollection_CollectionChanged; } #endregion #region Methods private void TrulyObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null) { foreach (Object item in e.NewItems) { (item as INotifyPropertyChanged).PropertyChanged += this.item_PropertyChanged; } } if (e.OldItems != null) { foreach (Object item in e.OldItems) { (item as INotifyPropertyChanged).PropertyChanged -= this.item_PropertyChanged; } } } private void item_PropertyChanged(object sender, PropertyChangedEventArgs e) { var a = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset); OnCollectionChanged(a); } #endregion } private class DataPoint : INotifyPropertyChanged { #region Fields private int itemCount; #endregion #region Public Events public event PropertyChangedEventHandler PropertyChanged; #endregion #region Public Properties public int ItemCount { get { return itemCount; } set { itemCount = value; this.OnPropertyChanged("ItemCount"); } } #endregion #region Methods protected virtual void OnPropertyChanged(string propertyName = null) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } #endregion } } }

Recommend

  • Execute method every specific time(ms)
  • WPF - Delayed Multibinding
  • Animate Image when loaded in Image Control
  • Execute a method after delay on time only
  • How to convert an array of int16 sound samples to a byte array to use in MonoGame/XNA
  • How can I hide extra divs with an ellipsis?
  • Service {ServiceName} was not found on computer '.'
  • Vim syntax highlighting for multiline fortran openmp directives
  • Automatic series in gnuplot?
  • Angular: Binding to a observable property of service -> value doesn't update
  • How to make object in List eligible for garbage collection?
  • Angular2 - How to Abort/cancel running http request calls?
  • Matlab FFT and FFTW
  • Convert a plain string[] into a Observable and concat it to another Observable using RxJS 5
  • KnockoutJS Forcing A Computed Observable to Re-Compute
  • DataView RowFilter with TimeSpan DataType
  • Can I return raw json response in angular2
  • Knockout.js mapping options being ignored on nested values
  • At what point is code reordering in C++ optimization stopped?
  • About multiple inheritance and ambiguity
  • How to ignore all from an observable if the other observable has data in RxJS?
  • Does as-if rule prevent compiler reordering of accesses to global/member variables?
  • PHP: Convert single-quoted string into double-quoted
  • UDPClient Receive method not working in a service
  • Thread.Join on multiple threads with timeout
  • Retrieve a list of filenames in folder and all subfolders quickly
  • Wait for subscription to complete
  • Azure service bus paired namespace - simulate failover
  • function cannot execute on segment because it accesses relation
  • Does many include's (in “case”) in ASP classic hurt the performance of the server?
  • How to prevent TreeItem selection?
  • How can I get new CSRF token in LARAVEL by using ajax
  • Catch in Observable stops HTTP Calls from Observable.interval
  • Angular5 Service Worker update(SWUpdate) not detecting on firefox. Working on chrome
  • MySql - get days remaining
  • data.table replicate rows after join?
  • Runtime.exec() gives Error: Could not find or load main class
  • Specifying Castle WCF Integration Facility Endpoint Behavior per Endpoint
  • How to model a transition system with SPIN
  • Change div Background jquery