I love the Reactive Framework, I will get to why in a minute. I even did a talk on it at the Guerrilla.NET class in May. That talk didn’t go so well because they keep changing the freakin’ API! Every single time I upgrade I have to fix things. This last class unfortunately I didn’t even realize that I was upgrading. I made the mistake of creating a project from scratch and using NuGet to pull down the latest version of Reactive. All of the Demo code that I was using broke in subtle ways that I couldn’t quite figure out live, so I had to pull out a project that I had built a week prior. I just now had the time to sift through the changes and make everything work again.
There are still two major ways to subscribe to UI events. The API used to be called FromEvent, now it is FromEventPattern, even though FromEvent still exists for some reason. The important part isn’t whether th API is called FromEvent or FromEventPattern. The distinguishing feature is whether you pass one generic type argument or two. If you just pass one you get access to use the old string method like this:
var mousemoves1 = from evt in Observable.FromEventPattern<MouseEventArgs>(rect, "MouseMove") select evt.EventArgs.GetPosition(LayoutRoot);
If you pass in two arguments (the first being the delegate type, and the second being the EventArgs type) you get to use the more confusing, but more flexible API. It makes sense after you think about it for a while. That one looks like this:
var mousemoves2 = from evt in Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( h => MouseMove += h, h => MouseMove -= h) select evt.EventArgs.GetPosition(LayoutRoot);
The reason you can’t simple pass MouseMove is because the add_ and remove_ methods for the event aren’t exposed directly.
Anyway, one of the best features of Reactive is the fact that you can transform a set of UI specific events that can only be handled by the UI to a set of events that can be handled by anyone, a ViewModel for instance.
var textChanged = Observable.FromEventPattern<TextChangedEventHandler, TextChangedEventArgs>( h => textBox.TextChanged += h, h => textBox.TextChanged -= h); var stringsChanging = from tc in textChanged select ((TextBox)tc.Sender).Text; // Now that we have transformed these events we can pass // them safely into the ViewModel // which will still know nothing of how they were generated viewModel.SetupSubscription(stringsChanging);
The idea of transforming an passing around events is one of the main reasons why I still love Reactive even though they break me every month or so…