punker76 / gong-wpf-dragdrop

The GongSolutions.WPF.DragDrop library is a drag'n'drop framework for WPF
BSD 3-Clause "New" or "Revised" License
2.31k stars 401 forks source link

It seems that DropHandler and DragHandler are not working together when both set #428

Closed lmuestak closed 2 years ago

lmuestak commented 2 years ago

Introduction I have the following interface which also implements the IDropTargetand IDragSource.

    public interface IFolderBrowserViewModel : IViewModelBase, IDragSource, IDropTarget
    {
        ...
    }

There is also a corresponding class called FolderBrowserViewModel which implements the IFolderBrowserViewModel interface.

    public class FolderBrowserViewModel: ViewModelbase, IFolderBrowserViewModel
   {
        ...

        public void DragOver(IDropInfo dropInfo)
        {
            ...

        }

        public void Drop(IDropInfo dropInfo)
        {
            ...
        }

        public void Dropped(IDropInfo dropInfo){  }

        public void StartDrag(IDragInfo dragInfo)
        {
            //if (dragInfo.VisualSource is TreeView || dragInfo.VisualSource is TreeViewItem)
            //{
            //    Debug.WriteLine($"Drag source is TreeView/TreeViewItem {dragInfo.SourceItem}");
            //}
        }

        public bool CanStartDrag(IDragInfo dragInfo)
        {
            return true;
        }

        public void DragDropOperationFinished(DragDropEffects operationResult, IDragInfo dragInfo){  }
        public void DragCancelled(){  }

        public bool TryCatchOccurredException(Exception exception)
        {
            return true;
        }

   }

The user control FolderBrowserView I'm using is containing a TreeView element with the following configuration:


<TreeView 
        dd:DragDrop.IsDragSource="True"
        dd:DragDrop.IsDropTarget="True"
        dd:DragDrop.DragAdornerTemplate="{StaticResource FolderDragAdorner}"
        dd:DragDrop.SelectDroppedItems="True"
        dd:DragDrop.DropHandler="{Binding}"
        dd:DragDrop.DragHandler="{Binding}"
        dd:DragDrop.DropTargetAdornerBrush="LightSkyBlue"
        dd:DragDrop.DragDirectlySelectedOnly="True">
      ...
</TreeView>

The issue

If only one of the properties is set then the drag and drop seems to work.

<TreeView 
...
dd:DragDrop.DropHandler="{Binding}">
...
</TreeView>

or like

<TreeView 
...
dd:DragDrop.DragHandler="{Binding}">
...
</TreeView>

But if I set both properties then nothing works.

<TreeView 
...
dd:DragDrop.DropHandler="{Binding}"
dd:DragDrop.DragHandler="{Binding}">
...
</TreeView>

Any ideas what the problem is?

punker76 commented 2 years ago

@lmuestak I tried to reproduce this with the following code. But I don't see an issue here. Is there maybe some other code not working or an exception thrown?

    public interface IDragDropHandler : IDragSource, IDropTarget
    {
    }

    public class MainViewModel : ViewModelBase, IDragDropHandler
    {
        public void StartDrag(IDragInfo dragInfo)
        {
            GongSolutions.Wpf.DragDrop.DragDrop.DefaultDragHandler.StartDrag(dragInfo);
        }

        public bool CanStartDrag(IDragInfo dragInfo)
        {
            return GongSolutions.Wpf.DragDrop.DragDrop.DefaultDragHandler.CanStartDrag(dragInfo);
        }

        public void Dropped(IDropInfo dropInfo)
        {
            GongSolutions.Wpf.DragDrop.DragDrop.DefaultDragHandler.Dropped(dropInfo);
        }

        public void DragDropOperationFinished(DragDropEffects operationResult, IDragInfo dragInfo)
        {
            GongSolutions.Wpf.DragDrop.DragDrop.DefaultDragHandler.DragDropOperationFinished(operationResult, dragInfo);
        }

        public void DragCancelled()
        {
        }

        public bool TryCatchOccurredException(Exception exception)
        {
            return false;
        }

        public void DragEnter(IDropInfo dropInfo)
        {
            GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.DragEnter(dropInfo);
        }

        public void DragOver(IDropInfo dropInfo)
        {
            GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.DragOver(dropInfo);
        }

        public void DragLeave(IDropInfo dropInfo)
        {
            GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.DragLeave(dropInfo);
        }

        public void Drop(IDropInfo dropInfo)
        {
            GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.Drop(dropInfo);
        }
    }

The binding is to the MainViewModel

<TreeView dd:DragDrop.IsDragSource="True"
          dd:DragDrop.IsDropTarget="True"
          dd:DragDrop.DragHandler="{Binding}"
          dd:DragDrop.DropHandler="{Binding}"
          dd:DragDrop.UseDefaultDragAdorner="True"
          dd:DragDrop.UseDefaultEffectDataTemplate="True"
          dd:DragDrop.SelectDroppedItems="True"
          ItemsSource="{Binding Data.TreeCollection1}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <TextBlock Margin="2" Text="{Binding Caption}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

gong_dragdrop_interface

lmuestak commented 2 years ago

Hi @punker76,

Im not able to drag or drop when both are handlers are set (drag and drop adorners are not visible and not moving). And there is also not exception in code. My goal is to drag some items from the treeview or listview onto to windows explorer to copy them. if drophandler is set then im able drag and drop items between treeview/treeview treeview/listview or listview/listview.

unfortunetly, im sitting so long an that issue.

I've created a simple project to simulate a windows explorer here: DragDop Demo Can we change the code, so that I'm able to drag the folders my explorer somewhere to windows explorer or windows desktop?

Thanks in advance! Best regards

punker76 commented 2 years ago

@lmuestak Thanks for the sample and clarifying the issue. If you want to do a file drop then you can use your own DataObject to set the SetFileDropList.

        public void StartDrag(IDragInfo dragInfo)
        {
            // drag&drop inside the ListBox with control key
            if (Keyboard.Modifiers.HasFlag(ModifierKeys.Control))
            {
                GongSolutions.Wpf.DragDrop.DragDrop.DefaultDragHandler.StartDrag(dragInfo);
            }
            else
            {
                var files = dragInfo.SourceItems.OfType<FileModel>().Select(f => f.File).ToArray();

                var dataObject = new DataObject();
                var sc = new System.Collections.Specialized.StringCollection();
                sc.AddRange(files!);
                dataObject.SetFileDropList(sc);

                dragInfo.DataObject = dataObject;
                dragInfo.Effects = DragDropEffects.Copy;
            }
        }

I have created a full sample where you can drop files on and drag files to the explorer.

https://github.com/punker76/gong-wpf-dragdrop-file-sample

lmuestak commented 2 years ago

Hi @punker76,

thank you so much for help. Unfortunetly the link to your full example is not available. https://github.com/punker76/gong-wpf-dragdrop-file-sample

image

Best regards

punker76 commented 2 years ago

@lmuestak Sorry, it was private, it's now public.

lmuestak commented 2 years ago

Now, its available. Thanks a lot!

punker76 commented 2 years ago

@lmuestak Can i close this issue now?

lmuestak commented 2 years ago

@punker76 Yes, thanks a lot!