public void Receive(DependencyObject value) { var control = (UIElement) value; control.AllowDrop = true; var window = Window.GetWindow(value); DragAdorner adorner=null; var createAdorner = Observable.FromEventPattern<DragEventHandler, DragEventArgs> (h => control.PreviewDragEnter += h, h => control.PreviewDragEnter -= h) .Select(ev => ev.EventArgs) .Subscribe(e => { var files = (string[])e.Data.GetData(DataFormats.FileDrop); var container = new FileDropContainer(files); var contentPresenter = new ContentPresenter {Content = container}; adorner = new DragAdorner(control, contentPresenter); }); var clearAdorner = Observable.FromEventPattern<DragEventHandler, DragEventArgs>(h => control.PreviewDragLeave += h, h => control.PreviewDragLeave -= h).ToUnit() .Merge(Observable.FromEventPattern<DragEventHandler, DragEventArgs>(h => control.PreviewDrop += h, h => control.PreviewDrop -= h).ToUnit()) .Merge(Observable.FromEventPattern<DragEventHandler, DragEventArgs>(h => window.DragLeave += h, h => window.DragLeave -= h).ToUnit()) .Subscribe(e => { if (adorner == null) return; adorner.Detatch(); adorner = null; }); var updatePositionOfAdornment = Observable.FromEventPattern<DragEventHandler, DragEventArgs> (h => control.PreviewDragOver += h, h => control.PreviewDragOver -= h) .Select(ev => ev.EventArgs) .Where(_=>adorner!=null) .Subscribe(e => adorner.MousePosition = e.GetPosition(window)); var dropped = Observable.FromEventPattern<DragEventHandler, DragEventArgs> (h => control.Drop += h, h => control.Drop -= h) .Select(ev => ev.EventArgs) .SelectMany(e => { if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return Enumerable.Empty<FileInfo>(); // Note that you can have more than one file. var files = (string[]) e.Data.GetData(DataFormats.FileDrop); return files.Select(f => new FileInfo(f)); }) .SubscribeSafe(_fileDropped); _cleanUp.Disposable = Disposable.Create(() => { updatePositionOfAdornment.Dispose(); clearAdorner.Dispose(); createAdorner.Dispose(); dropped.Dispose(); _fileDropped.OnCompleted(); }); }
public void Receive(DependencyObject value) { var control = (UIElement)value; control.AllowDrop = true; var window = Window.GetWindow(value); DragAdorner adorner = null; var createAdorner = Observable.FromEventPattern <DragEventHandler, DragEventArgs> (h => control.PreviewDragEnter += h, h => control.PreviewDragEnter -= h) .Select(ev => ev.EventArgs) .Subscribe(e => { var files = (string[])e.Data.GetData(DataFormats.FileDrop); var container = new FileDropContainer(files); var contentPresenter = new ContentPresenter { Content = container }; adorner = new DragAdorner(control, contentPresenter); }); var clearAdorner = Observable.FromEventPattern <DragEventHandler, DragEventArgs>(h => control.PreviewDragLeave += h, h => control.PreviewDragLeave -= h).ToUnit() .Merge(Observable.FromEventPattern <DragEventHandler, DragEventArgs>(h => control.PreviewDrop += h, h => control.PreviewDrop -= h).ToUnit()) .Merge(Observable.FromEventPattern <DragEventHandler, DragEventArgs>(h => window.DragLeave += h, h => window.DragLeave -= h).ToUnit()) .Subscribe(e => { if (adorner == null) { return; } adorner.Detatch(); adorner = null; }); var updatePositionOfAdornment = Observable.FromEventPattern <DragEventHandler, DragEventArgs> (h => control.PreviewDragOver += h, h => control.PreviewDragOver -= h) .Select(ev => ev.EventArgs) .Where(_ => adorner != null) .Subscribe(e => adorner.MousePosition = e.GetPosition(window)); var dropped = Observable.FromEventPattern <DragEventHandler, DragEventArgs> (h => control.Drop += h, h => control.Drop -= h) .Select(ev => ev.EventArgs) .SelectMany(e => { if (!e.Data.GetDataPresent(DataFormats.FileDrop)) { return(Enumerable.Empty <FileInfo>()); } // Note that you can have more than one file. var files = (string[])e.Data.GetData(DataFormats.FileDrop); return(files.Select(f => new FileInfo(f))); }) .SubscribeSafe(_fileDropped); _cleanUp.Disposable = Disposable.Create(() => { updatePositionOfAdornment.Dispose(); clearAdorner.Dispose(); createAdorner.Dispose(); dropped.Dispose(); _fileDropped.OnCompleted(); }); }