Search code examples
mvvmsystem.reactivereactive-programming

Reactive Extensions (Rx) + MVVM =?


One of the main examples being used to explain the power of Reactive Extensions (Rx) is combining existing mouse events into a new 'event' representing deltas during mouse drag:

var mouseMoves = from mm in mainCanvas.GetMouseMove()
                 let location = mm.EventArgs.GetPosition(mainCanvas)
                 select new { location.X, location.Y};
                 
var mouseDiffs = mouseMoves
    .Skip(1)
    .Zip(mouseMoves, (l, r) => new {X1 = l.X, Y1 = l.Y, X2 = r.X, Y2 = r.Y});

var mouseDrag = from _  in mainCanvas.GetMouseLeftButtonDown()
                from md in mouseDiffs.Until(
                    mainCanvas.GetMouseLeftButtonUp())
                select md;

Source: Matthew Podwysocki's Introduction to the Reactive Framework series.

In MVVM I generally strive to keep my .xaml.cs file as empty as possible and one way of hooking up events from the view with commands in the viewmodel purely in markup is using a behavior:

<Button Content="Click Me">
    <Behaviors:Events.Commands>
        <Behaviors:EventCommandCollection>
            <Behaviors:EventCommand CommandName="MouseEnterCommand" EventName="MouseEnter" />
            <Behaviors:EventCommand CommandName="MouseLeaveCommand" EventName="MouseLeave" />
            <Behaviors:EventCommand CommandName="ClickCommand" EventName="Click" />
        </Behaviors:EventCommandCollection>
    </Behaviors:Events.Commands>
</Button>

Source: Brian Genisio.

The Reactive Framework seems to be more geared towards the traditional MVC pattern where a controller knows the view and can reference its events directly.

But, I want to both have my cake and eat it!

How would you combine these two patterns?


Solution

  • I've written a framework that represents my explorations in this question called ReactiveUI

    It implements both an Observable ICommand, as well as ViewModel objects who signal changes via an IObservable, as well as the ability to "assign" an IObservable to a property, who will then fire INotifyPropertyChange whenever its IObservable changes. It also encapsulates a lot of common patterns, like having an ICommand who runs a Task in the background, then marshalls the result back to the UI.

    I have absolutely zero documentation up right now, but I'll be working on adding that information over the coming days, as well as a sample application I've coded up

    UPDATE: I now have quite a lot of documentation up, check out http://www.reactiveui.net