Getting Started with Reactive Extensions (part 2)

This is the second post in the series about RX

  • part 1 – Intro
  • part 2 – Mouse Events
  • part 3 – Complex Collection Events
  • part 4 – Client Server Async
  • </ul>

    Demo – simple mouse move

    On my previous post I explained what RX is and how to get started with it. Now will go through some examples.

    Consider the following window, where the mouse moves and you want to capture the mouse location. Notice I have no buttons to “catch” or “apply” the mouse position and I just want to track the current hovered item.

    clip_image002

    Without RX I had to open a timer and manage some sort of state machine to track the changes along the timer ticks. If I wanted to track the mouse only when the mouse stops moving I would have ended up with two timers or a much complex state machine. With RX I just have to set the following:

    Observable.FromEventPattern(this, "MouseMove")
        .Throttle(TimeSpan.FromSeconds(1))
        .ObserveOnDispatcher()
        .Subscribe(ShowColor);
    </pre>
    

    What we did here is create an observer on the mouse move, and the Throttle (wait for) 1 second till the mouse stops moving, observer on the dispatcher (UI thread) and finally, subscribe using a method to show the result

    if (VisualTreeHelper.HitTest(blueBorder, e.EventArgs.GetPosition(blueBorder)) != null)
    {
        MouseColors.Add("Blue");
    }
    else if (VisualTreeHelper.HitTest(greenBorder, e.EventArgs.GetPosition(greenBorder)) != null)
    .
    .
    .
    

    Now, we can take this a step further and listen to a particular event for each of the borders instead of just HitTesting where the mouse is

    //observer directly the control with merge
    
    Observable.FromEventPattern(blueBorder, "MouseMove")
        .Merge(Observable.FromEventPattern(greenBorder, "MouseMove"))
        .Merge(Observable.FromEventPattern(redBorder, "MouseMove"))
        .Merge(Observable.FromEventPattern(yellowBorder, "MouseMove"))
        .Throttle(TimeSpan.FromSeconds(1))
        .ObserveOnDispatcher()
        .Subscribe(ShowColor2);
    </pre>
    

    Notice that I merge different events into one subscription. We can take this even further by only propagating changes – so if the mouse moves over just one border will not raise a new subscription event (DistinctUntilChange)

     Observable.FromEventPattern(blueBorder, "MouseMove")
       .Merge(Observable.FromEventPattern(greenBorder, "MouseMove"))
       .Merge(Observable.FromEventPattern(redBorder, "MouseMove"))
       .Merge(Observable.FromEventPattern(yellowBorder, "MouseMove"))
       .Throttle(TimeSpan.FromSeconds(1))
       .DistinctUntilChanged(e => e.Sender) //new 
       .ObserveOnDispatcher()
       .Subscribe(ShowColor2);
    </pre>
    

    On the next post I’ll have a more complex demo using collections.

     

    Code for this demo here

Developer