FileExplorer3-TouchDrag.png
DragDropLiteEventProcessor allow user to perform non-shell based (e.g. no DoDragDrop called) drag, this means it only support drag drop inside an application.
For shell based Drag, uses DragDropEventProcessor instead.

The main reason for developing this is for Touch dragging support, because one cannot obtain touch information after DoDragDrop is called. This processor support both mouse and touch.

Similar to MultiSelectEventProcessor, one have to touch and hold on selected items for 0.5 seconds before drag.

How to use?

Xaml
To use it, add the processor to UIEventAdapter
<bc:UIEventAdapter.Processors>
       <bc:DragDropEventProcessor EnableDrag="True" EnableDrop="True" />
       <bc:DragDropLiteEventProcessor EnableDrag="True" EnableDrop="True" />
</bc:UIEventAdapter.Processors>

The above sample register both Shell and non-shell support, in this case, mouse drag will be shell supported, while touch drag works in the application only.

Because of the implementation, implementer also have to add a processor to the parent control (e.g. Window), to handle when drag to non-droppable position.
<bc:UIEventAdapter.Processors>
      <bc:DragDropLiteEventProcessor /> <!-- Default EnableDrag/Drop is false -->
</bc:UIEventAdapter.Processors>


View Model
To support drag, you have to implement ISupportDrag or ISupportDragHelper, which allow return dragging items and converter to DataObject.

To support drop, you have to implement ISupportDrop or ISupportDropHelper, which query and complete the drag and drop operations.

In most case you can use the implemented LambdaDragHelper, DragHelper, DragHelper<T> and LambdaDrogHelper, DropHelper, DropHelper<T>.

For examples, taken from NonShellDragDemo
//Convert from IDraggable (implemented by ViewModel) 
//to Model (value transferred from dragsource to drop target).
var converter = new LambdaValueConverter<IDraggable, NumberModel>(
    d => (d is NumberViewModel) ? (d as NumberViewModel).Model : null,
    nm => new NumberViewModel(nm));

DragHelper = new LambdaDragHelper<NumberModel>(converter,
    //GetModels()
    () => Items.Where(nvm => nvm.IsSelected).Select(nvm => nvm.Model).ToList(),
    nms => DragDropEffects.Move, //OnQueryDrag(models)
    (nms, eff) =>
    {
        //OnDropCompleted(models, dropEffect)
        foreach (var nm in nms)
            Items.Remove(new NumberViewModel(nm));
    }
    );
DropHelper = new LambdaDropHelper<NumberModel>(converter,
    (nms, eff) =>
    {
        //OnQueryDrop(models, possibleEffects)
        foreach (var nm in nms)
            if (Items.Any(ivm => ivm.Model.Equals(nm)))
                return QueryDropEffects.None;
        return QueryDropEffects.CreateNew(DragDropEffects.Move);
    },
    (nms, eff) =>
    {
        //OnDrop(models, possibleEffects)
        foreach (var nm in nms)
            Items.Add(new NumberViewModel(nm));
        return DragDropEffects.Move;
    }) { DisplayName = displayName };


NonShellDragDemo.png

The implementation as follows:

DragDropLiteUIEventProcessor.png
p.s. the comment box are IScriptCommands thats shared with DragDropEventProcessor.
p.s. Updated, please see source

Last edited Oct 17, 2014 at 5:30 PM by lycj, version 14

Comments

No comments yet.