Loading user information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading user information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Rx Workshop: Reactive Coincidence

21 minutes, 59 seconds


Right click “Save as…”

Learn how to model events with duration and how to use the LINQ Join operator to express complex queries involving coincidence.

Download the Challenge


Follow the discussion

  • Oops, something didn't work.

    Getting subscription
    Subscribe to this conversation
  • Allan LindqvistaL_ Kinect ftw

    awsome stuff.. Smiley


  • Am I allowed to post the solution of the challange?


  • Aaron StainbackAceHack AceHack

    Here is what I came up with

                var query = Observable.Join(
                    _ => mouseUp, 
                    _ => Observable.Empty<Unit>(), 
                    (_, r) => r)
                    .Publish(evt => evt.Zip(evt.Skip(1), 
                        (previous, current) => Subtract(current, previous)));

    I am having difficulty translating this into query comprehension syntax.  Anyone figure that out?  Thanks.

  • Aaron StainbackAceHack AceHack

    Alright here is a working query comprehension version

    var query = from start in mouseDown
                join move in mouseMove
                on mouseUp equals Observable.Empty<Unit>() into moveGroup
                let drag = moveGroup.Zip(moveGroup.Skip(1),
                    (prev, curr) => Subtract(curr, prev))
                from delta in drag
                select delta;

    Still curious if this could be cleaner.  Thanks.


  • MrLovebucketMrLovebucket

    Here is my solution:

    var query = Observable.Join(
    _ => mouseUp,
    m => Observable.Empty<Unit>(),
    (_, r) => Subtract(r.Last(),r.First()));

  • I think my solution is close to the optimum!?

    But I had to modify the subscibtion from deltas to absolute points.

       var query = mouseDown.Join(mouseMove, l => mouseUp, r => Observable.Empty<Point>(),(l,r)=> Subtract(r,l));
                    Canvas.SetLeft(image, pos.X);
                    Canvas.SetTop(image, pos.Y);

  • Aaron StainbackAceHack AceHack

    I notied there is a bug when releasing the mouse button from outside of the window.  Here is a fix that will merge mouseUp and mouseLeave to accomplish the task.  What is normal UI guidance for drag and drop when going outside the window?  Thanks.

                var mouseLeave = from evt in Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => MouseLeave += h, h => MouseLeave -= h)
                                 select evt.EventArgs.GetPosition(this);
                var query = from start in mouseDown
                            join move in mouseMove.Buffer(2)
                            on mouseUp.Merge(mouseLeave) equals Observable.Empty<Unit>()
                            select Subtract(move.Last(), move.First());

  • Aaron StainbackAceHack AceHack

    Hey what happened to the challenges.  They are showing up 404.  I was trying to dowload again.  Thanks.

  • Here is my (edited) suggestion:

    .Buffer(2, 1)
    .Select(b => b[1] - b[0])
    .Window(mouseDown, _ => mouseUp)

    The Subtract method is not needed.

  • What I ended up with in query and fluent:
                var query = from down in mouseDown
                            join delta in
                                from move in mouseMove.Buffer(2)
                                select Subtract(move.Last(), move.First())
                                on mouseUp equals Observable.Empty<Unit>() 
                            select delta;
    //            var query = Observable.Join(
    //                mouseDown,
    //                mouseMove.Buffer(2).Select(b => Subtract(b.Last(), b.First())),
    //                _ => mouseUp,
    //                _ => Observable.Empty<EventArgs>(),
    //                (_, r) => r);
    ...though interested if anyone came up with a way to buffer then collapse after the join (I battered my head against that approach for a while before going for this).
    Also ended up with the same sln as BennyG first time after missreading the subscribe lambda...


    Here is a solution that uses the Scan method:

    var query = mouseDown.Join(
    .Scan(new { Prev = new Point(), Delta = new Point() },
    (current, next) => new { Prev = next, Delta = Subtract(next, current.Prev) })
    .Select(x => x.Delta),
    down => mouseUp,
    delta => Observable.Empty<Unit>(),
    (down, delta) => delta);

  • GeoffreyGeoffreyk boom

    reopening comments

  • My solution was based on a similar handling by SelectMany().

    private void DragAndDrop()
                var mousedown = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => image.MouseDown += h,
                                                                                                           h => image.MouseDown -= h)
                                          .Select(e => e.EventArgs.GetPosition(image));
                var mousemove = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => image.MouseMove += h,
                                                                                               h => image.MouseMove -= h)
                                          .Select(e => e.EventArgs.GetPosition(canvas));
                var mouseup = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => image.MouseUp += h,
                                                                                                         h => image.MouseUp -= h)
                                        .Select(e => e.EventArgs.GetPosition(image));
                var query = Observable.Join( mousedown
                                            ,p1 => mouseup
                                            ,p2 => Observable.Empty<Point>()
                                            ,(p1, p2) => new { X = p2.X - p1.X, Y = p2.Y - p1.Y }
                                     .Subscribe(p => { Canvas.SetLeft(image, p.X); Canvas.SetTop(image, p.Y); });

Remove this comment

Remove this thread


Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.