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

RadTreeView control drag and drop actions

11 Answers 623 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Hadrien
Top achievements
Rank 1
Hadrien asked on 26 Apr 2013, 12:40 PM
Hi,

I have a RadTreeView which allows drag and drop between nodes. There are different kind of nodes (classes which implement RadTreeViewItem) and I would like to set for each item class if they can be drag and if they can accept a drop (depending on the drag item source class).
I found the "AllowDrop" propriety in RadTreeViewItem class, but I cannot find anything like "AllowDrag" or "IsDraggable".

How should I implement this?

11 Answers, 1 is accepted

Sort by
0
Tina Stancheva
Telerik team
answered on 01 May 2013, 01:06 PM
Hello Hadrien,

We're currently working on the RadTreeView built-in DragDrop logic. Up until now it used to work with the old RadDragAndDropManager. And we're currently migrating this logic to use the new DragDropManager.

We've already released most of the changes with the Q1 2013 SP1 release (v. 2013.1.403) but we added a few new features in the latest internal build as well. We're targeting the Q2 2013 as the official release of the updated DragDrop logic of the control and we're currently gathering feedback regarding the new features. And we will highly appreciate it if you can download the latest internal build and test your application with it and with the new DragDrop logic.

Now to get straight to your question - if you're using our latest version, then it its best to set the telerik:TreeViewSettings.DragDropExecutionMode attached property to New and use the new DragDrop logic. Then you can think of the RadTreeView DragDrop logic in the context of the DragDropManager events and properties. This means that you have a few options to disable the drag operation when a particular item is being dragged:
  • You can use data-binding to bind the DragDropManager.AllowCapturedDrag and DragDropManager.AllowDrag attached properties. These two properties define whether any object can be dragged or not. However, in the RadTreeView we have a IsDragDropEnabled property that is responsible for the overall Drag/Drop-enabled state of the control. This is why when you set the IsDragDropEnabled property to True, the control will apply the AllowCapturedDrag and AllowDrag properties to True for all RadTreeViewItems. Unfortunately as this is implemented behind the scenes, you can't have a custom style setting the RadTreeViewItems DragAllowed settings to False at the same time. The Style settings will be overriden by the built-in logic of the control. However, in a data-binding scenario, you can have two different business objects that together define if an item can be dragged or not. This approach should include a property that controls if an item can be dragged at all and another property that should be data-bound to the DragDropManager.AllowCapturedDrag and DragDropManager.AllowDrag attached properties. Once you define these properties, you can use the first one to decide whether or not to update the second one. I demonstrated this approach in a sample solution so that you can have a closer look at it and consider whether it is a good option for you.
  • Another option is to handle the ItemPrepared event - when the RadTreeView.ItemsSource collection is populated with business data, the ItemPrepared event is fired for every business object once its RadTreeViewItem container is generated and fully initialized. This makes this event a good place to change the values of the DragDropManager.AllowCapturedDrag and DragDropManager.AllowDrag attached properties.
  • The next option is to handle the DragDropManager DragInitialize event handler for the RadTreeView:

DragDropManager.AddDragInitializeHandler(xTreeBinded, OnDragInitialize, true);
...
private void OnDragInitialize(object sender, DragInitializeEventArgs args)
        {
            var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions;
            if (options == null) return;
            if (!(options.DragSourceItem.Item as DataItem).IsDraggable)
                args.Cancel = true;
        }
Once you do that, you can access the dragged RadTreeViewItem and create custom logic that defines whether to cancel the drag operation.

I hope this information will help you and if you believe that we should provide a better option to implement your requirements, please let us know. As we're still gathering feedback on the DragDrop implementation, your input will be highly appreciated. Regards,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Hadrien
Top achievements
Rank 1
answered on 06 May 2013, 08:42 AM
Thanks for the full reply!
I'm using the DragDropManager approach, but after some tests I'm having a problem. So if I run the example you posted and put a breakpoint inside the next function and then if start dragging in an element of the first level of the tree, this function is called once, which is ok. But when I start dragging an element from the second level of depth the function is called twice, is there any reason for that?

private void OnDragInitialize(object sender, DragInitializeEventArgs args)
{
var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions;
if (options == nullreturn;
if (!(options.DragSourceItem.Item as DataItem).IsDraggable)
args.Cancel = true;
}
0
Tina Stancheva
Telerik team
answered on 09 May 2013, 01:37 PM
Hi Hadrien,

The DragDropManager is designed to propagate its events through the hierarchy of elements in the visual tree when an operation is unsuccessful. In our case with the RadTreeView control, when you cancel the drag operation while initializing the drag of a child, the DragDropManager will propagate the OnDragInitialize event to the parent of the child - the parent TreeViewItem. This is why the event is fired twice.

Unfortunately this means that if the parent can be dragged, the drag operation will succeed and it will be considered as initiated by the parent item. But the dragged item will still be the child, even though we tried to cancel the operation. This is a case, that we haven't considered thoroughly within the new DragDropManager implementation in the RadTreeView. And thanks to your feedback, we are currently working on it and we will do our best to provide a solution that allows you to deny the drag of an item despite its position in the hierarchy.

I updated your Telerik account for your feedback and I hope that you can wait for the Q2 2013 official release to implement your dragging requirements in the RadTreeView.

All the best,
Tina Stancheva
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Hadrien
Top achievements
Rank 1
answered on 07 Jun 2013, 12:42 PM
How long (+/-) it will take until you release the new version?
0
Tina Stancheva
Telerik team
answered on 10 Jun 2013, 04:52 PM
Hello Hadrien,

The new DragDrop implementation of the RadTreeView is already available within our Q2 2913 Beta release and the official Q2 2013 release is just around the corner.

Please make sure to download and test the new implementation as soon as you have a chance and let us know if you have any further questions or comments.

Regards,
Tina Stancheva
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Hadrien
Top achievements
Rank 1
answered on 12 Jun 2013, 08:40 AM
Hi,

I got the project example provided in the second post and then I update the references in order to use your latest version:
RadControls_for_WPF_2013_2_0531_Dev / Q2 2013 Beta - Automatic Installation

But I still having the same problem: I cannot drag a child of odd root node, for example, I cannot drag a item which is inside the Item 1. This happens because the second time the drag event is fired is at parent level and the parent is not dragable so all children won't be as well.

Are you going to fix this for the official Q2 2013 official release?
0
Tina Stancheva
Telerik team
answered on 17 Jun 2013, 11:56 AM
Hi Hadrien,

Thank you for getting back to us. We did consider a scenario where a parent item cannot be dragged, while a few of its children can. And in order to implement such a behavior you need to slightly modify the OnDragInitialize() event handler.

Specifically, you need to make sure that the object that raised the event (the OriginalSource) is the dragged item and only then cancel the operation based on the draggable property of the business data. You can check to see of the original source of the event is included in the TreeViewDragDropOptions DraggedItems collection:
private void OnDragInitialize(object sender, DragInitializeEventArgs args)
{
    var options = DragDropPayloadManager.GetDataFromObject(args.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions;
    if (options != null)
    {
        var source = args.OriginalSource as RadTreeViewItem != null ? (args.OriginalSource as RadTreeViewItem).Item as DataItem : null;
        if (options.DraggedItems.Contains(source))
        {
            args.Cancel = !source.IsDraggable;
        }
        else
        {
            args.Cancel = true;
        }
 
    }
}

I modified my solution to demonstrate this approach and to also reference the Q2 2013 official version of our controls. Please give it a try and let me know if it works for you.

Regards,
Tina Stancheva
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Anuj
Top achievements
Rank 1
answered on 01 Jul 2014, 10:04 AM
Hi Tina,

i was waiting for some answer on my post. but i hope you can help me on this.
 
I am using telerik Radtreeview. and i am performing drag and drop from radtreeview to RadScrollablePanel.
it is working fine but when i drag the tree node and drop in panel it goes to top-left location in panel every time.
i want to place it where i leave the cursor.
means can i get the location of treenode when i drop so i can bind it with the cursor.position.
 
Please reply.
 
Thanks in Anticipation
Anuj
0
Pavel R. Pavlov
Telerik team
answered on 02 Jul 2014, 01:46 PM

Hi Anuj,

I am not sure that I fully understand your particular scenario. Are you saying that you drop a EditableHeaderedItemsControl like the RadTreeViewItem into a panel (RadScrollablePanel)? How is that panel arranging the items? Would you mind sharing more information about your scenario? Sample, scaled down application will be really helpful to understand your scenario and investigate the reasons behind.

Thank you for your kind cooperation.

Regards,

Pavel R. Pavlov
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Joe
Top achievements
Rank 1
answered on 22 May 2017, 08:38 AM
[quote]Tina Stancheva said:Hi Hadrien,

The DragDropManager is designed to propagate its events through the hierarchy of elements in the visual tree when an operation is unsuccessful. In our case with the RadTreeView control, when you cancel the drag operation while initializing the drag of a child, the DragDropManager will propagate the OnDragInitialize event to the parent of the child - the parent TreeViewItem. This is why the event is fired twice.

Unfortunately this means that if the parent can be dragged, the drag operation will succeed and it will be considered as initiated by the parent item. But the dragged item will still be the child, even though we tried to cancel the operation. This is a case, that we haven't considered thoroughly within the new DragDropManager implementation in the RadTreeView. And thanks to your feedback, we are currently working on it and we will do our best to provide a solution that allows you to deny the drag of an item despite its position in the hierarchy.

I updated your Telerik account for your feedback and I hope that you can wait for the Q2 2013 official release to implement your dragging requirements in the RadTreeView.

All the best,
Tina Stancheva
the Telerik team
 

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

 

[/quote]

 

Hi, I'm using the Q3 2016 WPF UI library and can confirm that this bug still exists. If I cancel the drag of a RadTree node in the DragInitialize event via e.Cancel = true the DD manager will propagate the event up the tree to the next available parent node that can handle the drag. This is a dreadful oversite and may well mean that we have to unpick use of the Telerik controls. In certain areas of the application. How this bug is still not fixed considering it was known years ago is a huge oversight. Come on Telerik, sort it out. Very disappointing.

0
Petar Mladenov
Telerik team
answered on 25 May 2017, 08:10 AM
Hi Joe,

We understand your frustration and we will try to update our documentation resources to include this scenario. The way to actually cancel the DragInitialize in RadTreeView is to set e.Data and e.DragVisual to null.

DragDropManager.AddDragInitializeHandler(this.tree, OnDragInit, true);
 
private void OnDragInit(object sender, DragInitializeEventArgs e)
       {        
if (drag_dhould_be_cancelled)
{    
            e.Data = null;
            e.DragVisual = null;
}
       }

We hope this fits well in oyur sceanrio

Regards,
Petar Mladenov
Telerik by Progress
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Tags
TreeView
Asked by
Hadrien
Top achievements
Rank 1
Answers by
Tina Stancheva
Telerik team
Hadrien
Top achievements
Rank 1
Anuj
Top achievements
Rank 1
Pavel R. Pavlov
Telerik team
Joe
Top achievements
Rank 1
Petar Mladenov
Telerik team
Share this question
or