Item change tracking in DynamicData

Since ReactiveUI’s ReactiveList<T> has recently been deprecated, I’ve been moving to DynamicData.

One feature I used from ReactiveList was item change tracking. It might look something like this:

var myList = new ReactiveList<MyClass>();
myList.ChangeTrackingEnabled = true;
myList.ItemChanged
	.Where(x => x.PropertyName == nameof(MyClass.SomeProperty))
	.Select(x => x.Sender)
	.Subscribe(myObject =>
	{
		// Do some stuff
	});

In DynamicData it goes like this:

var myList = new SourceList<MyClass>();
myList
	.Connect()
	.WhenPropertyChanged(myObject => myObject.SomeProperty)
	.Subscribe(propValue =>
	{
		MyClass myObject = propValue.Sender;
		string newValue = propValue.Value;
		// Do some stuff
	});

There is also WhenValueChanged, which just gives you the new property value as a straight IObservable:

myList
	.Connect()
	.WhenValueChanged(myObject => myObject.SomeProperty)
	.Subscribe(newValue =>
	{
		// Do some stuff
	});

The most powerful is WhenAnyPropertyChanged, which can tell you when any of the properties changed:

var myList = new SourceList<MyClass>();
myList
	.Connect()
	.WhenAnyPropertyChanged()
	.Subscribe(myObject =>
	{
		// Do stuff with myObject
	});

Or when any set of specified properties has changed:

var myList = new SourceList<MyClass>();
myList
	.Connect()
	.WhenAnyPropertyChanged(nameof(MyClass.FirstProperty), nameof(MyClass.SecondProperty))
	.Subscribe(myObject =>
	{
		// Do stuff with myObject
	});

5 Replies to “Item change tracking in DynamicData”

  1. WhenAnyPropertyChanged is not available even after I

    using DynamicData;
    using DynamicData.Binding;
    using ReactiveUI;
    using ReactiveUI.Fody.Helpers;
    using System;
    using System.Reactive;
    using System.Reactive.Linq;
    using System.Threading.Tasks;

    1. Are you calling it on an IObservable after .Connect()? The extension method is in the DynamicData namespace on the latest version.

  2. I find out I need to implement INotifyPropertyChanged before it is available. I also use PropertyChanged.Fody. However, I am still stuck.

    private SourceList _myList { get; set; } = new SourceList();

    _myList.Connect()
    .ObserveOn(RxApp.MainThreadScheduler)
    //.ObserveOnDispatcher()
    .Bind(_targetCollection)
    .Subscribe();

    _myList.Connect()
    .WhenAnyPropertyChanged()
    .Subscribe( t =>
    {
    Debug.Print( t.customerName);
    }
    );

    which is attach to a winform grid. After making some change to an item in the grid, I expect I can find out which item has been changed, but it doesn’t seem to do anything. Yet, I can see the item has been changed in _myList.

    Can u provide me with a quick example of how this is done?

    1. I don’t know what happened.

      So I go ahead and remove the PropertyChanged.Fody package, and also the INotifyPropertyChanged.

      Now everything is working as expected, WhenAnyPropertyChanged is still available.

      _myList.Connect()
      .WhenAnyPropertyChanged()
      .Subscribe( t =>
      {
      Debug.Print( t.customerName);
      }
      );

      did tell me which item get changed as expected. Nice. Thanks a lot for your help

  3. Tracking change is good. However, is it possible I can get a list of changes when someone click a button like this?

    OKCmd = ReactiveCommand.Create(() =>
    {
    // Status = $”{EnteredText} is saved.”;
    var change = _myList
    .Connect()
    .QueryWhenChanged(
    {
    }
    );

    // );
    }

    I was hoping var change will contain a list of changes (how about new item?) so I can save the changes back to a database.

    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *