This is a migrated thread and some comments may be shown as answers.

Customize Drag Drop Visual

3 Answers 429 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Reilly
Top achievements
Rank 1
Veteran
Reilly asked on 12 Feb 2021, 04:58 PM

I am using the "UI for WPF Q1 2016" release, WPF, .NET Framework 4.6.1, Windows 10 and C#.

I am trying to implement drag and drop within a single RadTreeView. The default drag visual has a great structure, but has some problems for me. (The background of the drag item is dark and I can't read the dragged item's name, and the drop tooltip seems to be calling ToString() on my viewmodel, and that is not the text that I want.)

Researching, the page "Customize the TreeViewDragVisual" (https://docs.telerik.com/devtools/wpf/controls/radtreeview/how-to/customize-treeviewdragvisual)
tells me to derive from RadTreeView and to modify the template. But I am using NoXaml binaries and this page indicates that I must set the control template in app.xaml. Therefore it will apply to all RadTreeViews, and this doesn't seem like what I want to do.

Then I find the forum post on modifying the tooltip (https://www.telerik.com/forums/treeview---how-to-modify-the-drag-drop-drag-tooltip-target-part)
which points me at the DragDropManager. The manager has a "Set Drag Visual" topic (https://docs.telerik.com/devtools/wpf/controls/dragdropmanager/how-to/dragdrompmanager-howto-set-drag-visual) which says to handle DragDropManager.AddDragInitializeHandler and create a new drag visual in
the handler. This seems better than modifying app.xaml.

Also DragDropManager has the topic "Customizing the DragVisual" (https://docs.telerik.com/devtools/wpf/controls/dragdropmanager/behaviors/customizingdragvisual) which talks about implementing IDragVisualProvider. But the example is for ListBox and I'm using a RadTreeView.

So I'm all kinds of confused.

First, I need to fix the drag visual. I like the Drop Preview Line, the Drag Preview, and the Drag Tooltip parts. I need to change the Drag Preview and the Drag Tooltip.

Then I need to handle the "drop", which I think is done by attaching my own handler to DragDropManager.Drop event.

Thanks for any help.

-John.


3 Answers, 1 is accepted

Sort by
0
Dilyan Traykov
Telerik team
answered on 17 Feb 2021, 09:09 AM

Hello John,

The recommended approach, in this case, would be to indeed create a custom RadTreeView and handle the events provided by the DragDropManager.

If you do not wish to create an implicit style for the TreeViewDragVisual you can set a key for it in the App.xaml file and then set the style explicitly in the DragInitialize handler:

        private void OnDragInitialize(object sender, DragInitializeEventArgs args)
        {
            var treeDragVisual = args.DragVisual as TreeViewDragVisual;
            treeDragVisual.Style = App.Current.Resources["CustomDragVisual"] as Style;
        }
In the style you can change the appearance of the visual as desired.

As for updating the tooltip of the drop location, you can handle the DragOver event in a similar fashion:

        public void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs args)
        {
            var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions;
            
            var treeDragVisual = options.DragVisual as TreeViewDragVisual;

            // replace this with the text you want to display in the tooltip
            treeDragVisual.DropTarget = options.DropTargetItem.ToString();

            // override DropTargetTemplate if required
            // treeDragVisual.DropTargetTemplate = App.Current.Resources["DropTargetTemplate"] as DataTemplate;
        }
You can see that I get ahold of the TreeViewDragVisual and can then set its DropTarget and DropTargetTemplate properties.

Finally, you can also handle the Drop event as per your requirement:

        public void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs args)
        {
            var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions;
            var treeDragVisual = options.DragVisual as TreeViewDragVisual;

            // handle drop as desired
        }

For your convenience, I've prepared a small sample project which demonstrates how to set this up. Please have a look and let me know if you find it helpful.

Regards,
Dilyan Traykov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Reilly
Top achievements
Rank 1
Veteran
answered on 04 Mar 2021, 03:34 PM

Hi Dilyan,

This works for me. Thanks for the example.

I only have one question. Why did you derive a CustomTreeView class from the RadTreeView? Why didn't you just put the RadTreeView in the Example.xaml and then put the implementation in the Example.xaml.cs? That architecture works, because that's what I did. I thought that was the whole purpose of the DragDropManager.

Is it because you couldn't do the Style in app.xaml unless you derived the control?

Thanks again.

-John.

0
Dilyan Traykov
Telerik team
answered on 05 Mar 2021, 02:01 PM

Hi John,

I proposed this approach so that you can reuse this custom logic in multiple RadTreeView instances without duplicating code.

If you will only use a single RadTreeView instance, you can, of course, proceed with the architecture you've already set up.

I hope this clarifies your concerns. If any other questions arise, do not hesitate to contact me again.

Regards,
Dilyan Traykov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
TreeView
Asked by
Reilly
Top achievements
Rank 1
Veteran
Answers by
Dilyan Traykov
Telerik team
Reilly
Top achievements
Rank 1
Veteran
Share this question
or