Reactive Drag and Drop Part 1

Reactive Programming, Posting # 4

Continuing the discussion of Reactive Programming, this posting, based on a video from the Rx team, will create and annotate Drag and Drop using the Rx toolkit.  In part 1 we’ll track mouse movements, in part 2 we’ll implement drag and drop on an image.

Applying reactive programming to mouse movements treats the mouse as an observable collection of points and allows you to subscribe to that collection so that as new points become available you are notified.

To get started, create a new WPF Application (because we want to play with mouse movements).

Replace the grid with a canvas, and on the canvas add a TextBlock and an Image.  .

<Canvas>
   <TextBlock Name="textBlock" Text="Rx Drag and Drop" />
   <Image
      Name="image"
      Source="d:\avatar.png"
      Width="100"
      Height="100"
      Canvas.Left="25"
      Canvas.Top="25" />

</Canvas>

Make sure you’ve installed the Rx for .NET 4 libraries (available here) and in this project add references to System.CoreEx and System.Reactive.

We want to observe the mouse down/up and move events. The syntax is to create a variable, and assign to that variable the observer that we’ll create from the event. The FromEvent construct takes the name of the event args, the object on which the event will be raised, and the name of the event.  We can then select what values we want.

var mousedown = from evt in Observable.FromEvent
                   <MouseButtonEventArgs>(
                   this, "MouseDown" )
                select evt.EventArgs.GetPosition(
                   this );

We do the same with mouseup and mouse move

var mouseup = from evt in Observable.FromEvent
                 <MouseButtonEventArgs>(
                 this, "MouseUp" )
              select evt.EventArgs.GetPosition(
              this );
var mousemove = from evt in Observable.FromEvent
                   <MouseEventArgs>(
                   this, "MouseMove" )
                select evt.EventArgs.GetPosition(
                   this );

We can now create an observable that listens to the mouse positions from the time the mouse goes down and ending when the mouse goes up,

var q = from start in mousedown
        from pos in mousemove.StartWith( start )
        .TakeUntil( mouseup )
        select pos;

We can then subscribe to this observable and display the positions while the mouse button is down,

q.ObserveOnDispatcher()
   .Subscribe(
   value => textBlock.Text =
      value.ToString() );

The ObserveOnDispatcher forces back to the visual thread (so as not to throw an exception).

The subscribe method takes an Action, and so we can pass in a delegate to a method that assigns the string representation of the value to our text box.  In this case, as is customary we use a lambda expression to make the code easier to read and maintain.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Mini-Tutorial, Patterns & Skills, Reactive and tagged . Bookmark the permalink.

4 Responses to Reactive Drag and Drop Part 1

Comments are closed.