Tuesday, December 27, 2011

How to use FromEventPattern in Reactive Extensions (RX).

This example is about how to convert .NET events into an observable collection on which you can then done standard LINQ operations. The example demonstrates how to get removal notifications from an observable collection in a more declarative manner.
var strings = new System.Collections.ObjectModel.ObservableCollection<string>()
{
    "Item1", "Item2", "Item3"
};

var removals = 
Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>
(
    handler => strings.CollectionChanged += handler,
    handler => strings.CollectionChanged -= handler
)
.Where(e => e.EventArgs.Action == NotifyCollectionChangedAction.Remove)
.SelectMany(c => c.EventArgs.OldItems.Cast<string>());
    
var disposable = removals.Subscribe(GetDefaultObserver<string>("Removed"));
==========
Removed : Item1
Removed : Item2
==========
The observer was generated with this helper function:
public IObserver<T> GetDefaultObserver<T>(string onNextText)
{
    return Observer.Create<T>(
        x => Console.WriteLine("{0} : {1}", onNextText, x),
        ex => Console.WriteLine("OnError: {0}", ex.Message),
        () => Console.WriteLine("OnCompleted")
    );
}
The classical way how to achieve the same with an event handler would be:
strings.CollectionChanged += (sender, ea) => {
    if(ea.Action == NotifyCollectionChangedAction.Remove)
    {
        foreach (var oldItem in ea.OldItems.Cast<string>())
        {
            Console.WriteLine("Removed {0}", oldItem);    
        }
    }
};

1 comment:

  1. This post is almost three years old, and yet is the best explanation with code I found on the internet.
    Kudos to you and thank you for sharing.

    ReplyDelete