Permalink
Browse files

[WPF] Improve Drag and Drop

 - XWT expects immediate return from drag and drop, so we'll move the
   synchronous WPF call to the dispatcher
 - Need to raise the OnDragFinished event
 - Move DataObject stuff to DataConverter for possible reuse in clipboard
  • Loading branch information...
1 parent 53bd1da commit da8ee83ab710cc9c943bbd52666dc6014cbe9d9c @ermau ermau committed Apr 5, 2012
Showing with 32 additions and 20 deletions.
  1. +20 −0 Xwt.WPF/Xwt.WPFBackend/DataConverter.cs
  2. +12 −20 Xwt.WPF/Xwt.WPFBackend/WidgetBackend.cs
@@ -29,6 +29,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Specialized;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
@@ -429,5 +430,24 @@ public static ScrollPolicy ToXwtScrollPolicy (this SWC.ScrollBarVisibility visib
throw new NotSupportedException ();
}
}
+
+ public static DataObject ToDataObject (this TransferDataSource data)
+ {
+ var retval = new DataObject ();
+ foreach (var type in data.DataTypes) {
+ var value = data.GetValue (type);
+
+ if (type == TransferDataType.Text)
+ retval.SetText ((string)value);
+ else if (type == TransferDataType.Uri) {
+ var uris = new StringCollection ();
+ uris.Add (((Uri)value).LocalPath);
+ retval.SetFileDropList (uris);
+ } else
+ retval.SetData (type.Id, TransferDataSource.SerializeValue (value));
+ }
+
+ return retval;
+ }
}
}
@@ -653,27 +653,12 @@ public void DragStart (DragStartData data)
if (data.Data == null)
throw new ArgumentNullException ("data");
- var dataObj = CreateDataObject (data.Data);
- DragDrop.DoDragDrop (Widget, dataObj, data.DragAction.ToWpfDropEffect ());
- }
-
- static DataObject CreateDataObject (TransferDataSource data)
- {
- var retval = new DataObject ();
- foreach (var type in data.DataTypes) {
- var value = data.GetValue (type);
+ DataObject dataObj = data.Data.ToDataObject();
- if (type == TransferDataType.Text)
- retval.SetText ((string)value);
- else if (type == TransferDataType.Uri) {
- var uris = new StringCollection ();
- uris.Add (((Uri)value).LocalPath);
- retval.SetFileDropList (uris);
- } else
- retval.SetData (type.Id, TransferDataSource.SerializeValue (value));
- }
-
- return retval;
+ Widget.Dispatcher.BeginInvoke (
+ (Func<DependencyObject, object, DragDropEffects, DragDropEffects>)DragDrop.DoDragDrop,
+ Widget, dataObj, data.DragAction.ToWpfDropEffect ()
+ );
}
public void SetDragTarget (TransferDataType [] types, DragDropAction dragAction)
@@ -816,12 +801,16 @@ void WidgetDropHandler (object sender, System.Windows.DragEventArgs e)
bool res = Toolkit.Invoke (delegate {
eventSink.OnDragDropCheck (checkArgs);
});
+
if (checkArgs.Result == DragDropResult.Canceled || !res) {
e.Effects = DragDropEffects.None;
+ eventSink.OnDragFinished (new DragFinishedEventArgs (false));
return;
}
}
+ bool deleteSource = false;
+
if ((enabledEvents & WidgetEvent.DragDrop) > 0) {
var store = new TransferDataStore ();
FillDataStore (store, e.Data, DragDropInfo.TargetTypes);
@@ -831,11 +820,14 @@ void WidgetDropHandler (object sender, System.Windows.DragEventArgs e)
eventSink.OnDragDrop (args);
});
+ deleteSource = args.Success;
e.Effects = args.Success ? actualEffect : DragDropEffects.None;
}
// No DrapDropCheck/DragDrop event enabled.
e.Effects = DragDropEffects.None;
+
+ this.eventSink.OnDragFinished (new DragFinishedEventArgs (deleteSource));
}
void WidgetDragLeaveHandler (object sender, System.Windows.DragEventArgs e)

0 comments on commit da8ee83

Please sign in to comment.