Skip to content

Instantly share code, notes, and snippets.

@vkobel
Last active August 10, 2020 05:04
Show Gist options
  • Save vkobel/6552020 to your computer and use it in GitHub Desktop.
Save vkobel/6552020 to your computer and use it in GitHub Desktop.
Simple Drag & Drop with Reactive Extensions
using System;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace RxDragAndDrop {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
// Stream of mousedown events with special condition (must drag on the ball image)
var mouseDownOnBall = from mouseEvt in Observable.FromEventPattern<MouseButtonEventArgs>(this, "MouseDown")
let pos = mouseEvt.EventArgs.GetPosition(image)
where pos.X >= 0 && pos.Y >= 0 &&
pos.X <= image.Width && pos.Y <= image.Height
select mouseEvt;
// Stream mouseup events
var mouseUp = Observable.FromEventPattern<MouseButtonEventArgs>(this, "MouseUp");
// Stream of mouse postion on mousemove
var mouseMovePos = from md in Observable.FromEventPattern<MouseEventArgs>(this, "MouseMove")
select md.EventArgs.GetPosition(this);
// deltas of postions (before/after), zip the mousemove with itself to compute the delta
var mouseDeltas = mouseMovePos.Zip(mouseMovePos.Skip(1), (p, c) => new { X = c.X - p.X, Y = c.Y - p.Y });
// pushes the deltas of mouse positions only when the mouse is down on the ball image
var deltasOnDrag = from start in mouseDownOnBall
from moves in mouseDeltas.TakeUntil(mouseUp)
select moves;
// Subscription and modify the postion of the ball image
deltasOnDrag.Subscribe(val => {
Canvas.SetTop(image, Canvas.GetTop(image) + val.Y);
Canvas.SetLeft(image, Canvas.GetLeft(image) + val.X);
});
}
}
}
<Window x:Class="RxDragAndDrop.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="539">
<Canvas>
<TextBlock Name="textBlock" Text="!Rx!" />
<Image Name="image" Source="ball.png" Canvas.Top="30" Canvas.Left="0" Height="64" Width="64" />
</Canvas>
</Window>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment