Hello,
While comparing TreeView and TreeListView controls, I've found that the out-of-the-box visuals for DragDrop is much more complete for the TreeView than it is for the TreeListView. I've attached two images, the first showing the TreeView's preview, and the second is showing the TreeListView.
I could not find any examples of the TreeListView that would give a preview like "Drop before x..", can this be achieved for the TreeListView?
Thanks,
Ryan
While comparing TreeView and TreeListView controls, I've found that the out-of-the-box visuals for DragDrop is much more complete for the TreeView than it is for the TreeListView. I've attached two images, the first showing the TreeView's preview, and the second is showing the TreeListView.
I could not find any examples of the TreeListView that would give a preview like "Drop before x..", can this be achieved for the TreeListView?
Thanks,
Ryan
4 Answers, 1 is accepted
0
Hi Ryan,
It seems that the attachments are missing. However, custom dropIndication details can be achieved with RadTreeListView control. You can check this online demo which demonstrates how this is achieved for the TreeView (please check the TreeViewDragDropBehavior class). The same approach is applicable with little modifications for the TreeListView.
Regards,
Yoan
Telerik by Progress
It seems that the attachments are missing. However, custom dropIndication details can be achieved with RadTreeListView control. You can check this online demo which demonstrates how this is achieved for the TreeView (please check the TreeViewDragDropBehavior class). The same approach is applicable with little modifications for the TreeListView.
Regards,
Yoan
Telerik by Progress
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
0
Ryan
Top achievements
Rank 1
answered on 15 Aug 2016, 07:19 PM
Thanks for the references. Too bad there is not anything specific for the TreeListView. Is the drag and drop behavior for the TreeListView more closely related to the GridView, or the TreeView?
Using the behavior below, what pieces are missing for displaying the "drop before", "drop inside" tooltips?
Thanks,
Ryan
Using the behavior below, what pieces are missing for displaying the "drop before", "drop inside" tooltips?
Thanks,
Ryan
public class TreeViewDragDropBehavior { private object originalSource = null; private IList sourceCollection = null; private IList destinationCollection = null; private RadTreeListView _associatedObject; public IList SourceCollection { get { return this.sourceCollection; } set { this.sourceCollection = value; } } /// <summary> /// AssociatedObject Property /// </summary> public RadTreeListView AssociatedObject { get { return _associatedObject; } set { _associatedObject = value; } } private static Dictionary<RadTreeListView, TreeViewDragDropBehavior> instances; static TreeViewDragDropBehavior() { instances = new Dictionary<RadTreeListView, TreeViewDragDropBehavior>(); } public static bool GetIsEnabled(DependencyObject obj) { return (bool)obj.GetValue(IsEnabledProperty); } public static void SetIsEnabled(DependencyObject obj, bool value) { TreeViewDragDropBehavior behavior = GetAttachedBehavior(obj as RadTreeListView); behavior.AssociatedObject = obj as RadTreeListView; if (value) { behavior.Initialize(); } else { behavior.CleanUp(); } obj.SetValue(IsEnabledProperty, value); } // Using a DependencyProperty as the backing store for IsEnabled. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(TreeViewDragDropBehavior), new PropertyMetadata(new PropertyChangedCallback(OnIsEnabledPropertyChanged))); public static void OnIsEnabledPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { #if !SILVERLIGHT SetIsEnabled(dependencyObject, (bool)e.NewValue); #endif } public static TreeViewDragDropBehavior GetAttachedBehavior(RadTreeListView gridview) { if (!instances.ContainsKey(gridview)) { instances[gridview] = new TreeViewDragDropBehavior(); instances[gridview].AssociatedObject = gridview; } return instances[gridview]; } protected virtual void Initialize() { DragDropManager.AddDragInitializeHandler(this.AssociatedObject, OnDragInitialize, true); DragDropManager.AddDropHandler(this.AssociatedObject, OnDrop, true); DragDropManager.AddDragDropCompletedHandler(this.AssociatedObject, OnDragDropCompleted, true); DragDropManager.AddDragOverHandler(this.AssociatedObject, OnDragOver, true); this.AssociatedObject.DataLoaded += RadTreeListView1_DataLoaded; } protected virtual void CleanUp() { DragDropManager.RemoveDragInitializeHandler(this.AssociatedObject, OnDragInitialize); DragDropManager.RemoveDropHandler(this.AssociatedObject, OnDrop); DragDropManager.RemoveDragDropCompletedHandler(this.AssociatedObject, OnDragDropCompleted); DragDropManager.RemoveDragOverHandler(this.AssociatedObject, OnDragOver); this.AssociatedObject.DataLoaded -= RadTreeListView1_DataLoaded; } private void OnDragInitialize(object sender, DragInitializeEventArgs e) { var sourceRow = (e.OriginalSource as TreeListViewRow) ?? (e.OriginalSource as FrameworkElement).ParentOfType<TreeListViewRow>(); if (sourceRow != null) { var dataObject = DragDropPayloadManager.GeneratePayload(null); var draggedItem = sourceRow.Item; DragDropPayloadManager.SetData(dataObject, "DragData", new Collection<object>() { draggedItem }); e.Data = dataObject; var screenshotVisualProvider = new ScreenshotDragVisualProvider(); e.DragVisual = screenshotVisualProvider.CreateDragVisual(new DragVisualProviderState(e.RelativeStartPoint, new List<object>() { draggedItem }, new List<DependencyObject>() { sourceRow }, sender as FrameworkElement)); e.DragVisualOffset = new Point(0, 0); this.originalSource = sourceRow.Item; this.sourceCollection = sourceRow.ParentRow != null ? (IList)sourceRow.ParentRow.Items.SourceCollection : (IList)sourceRow.GridViewDataControl.ItemsSource; } } private void OnDragDropCompleted(object sender, DragDropCompletedEventArgs e) { } private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e) { if (e.Data != null && e.AllowedEffects != DragDropEffects.None) { Collection<Object> payload = DragDropPayloadManager.GetDataFromObject(e.Data, "DragData") as Collection<Object>; if (payload != null) { Folder droppedItem = (Folder)payload[0]; var destinationRow = e.OriginalSource as TreeListViewRow ?? (e.OriginalSource as FrameworkElement).ParentOfType<TreeListViewRow>(); if (destinationRow != null) { Folder targetItem = destinationRow.DataContext as Folder; TreeListViewDropPosition relativeDropPosition = (TreeListViewDropPosition)destinationRow.GetValue(RadTreeListView.DropPositionProperty); this.destinationCollection = relativeDropPosition == TreeListViewDropPosition.Inside ? (IList)destinationRow.Items.SourceCollection : destinationRow.ParentRow != null ? (IList)destinationRow.ParentRow.Items.SourceCollection : (IList)destinationRow.GridViewDataControl.ItemsSource; MoveItem(droppedItem, targetItem, relativeDropPosition); } else { this.destinationCollection = (IList)(sender as RadTreeListView).ItemsSource; MoveItemToRoot(droppedItem); } } } } private void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e) { var dropTarget = e.OriginalSource as TreeListViewRow ?? (e.OriginalSource as FrameworkElement).ParentOfType<TreeListViewRow>(); if (this.IsChildOf(dropTarget, this.originalSource)) { e.Effects = DragDropEffects.None; } e.Handled = true; } private bool IsChildOf(TreeListViewRow dropTarget, object originalSource) { var currentElement = dropTarget; while (currentElement != null) { if (currentElement.Item == originalSource) { return true; } currentElement = currentElement.ParentRow; } return false; } void RadTreeListView1_DataLoaded(object sender, EventArgs e) { this.AssociatedObject.DataLoaded -= new EventHandler<EventArgs>(RadTreeListView1_DataLoaded); this.AssociatedObject.ExpandAllHierarchyItems(); } private void MoveItemToRoot(Folder droppedItem) { var parentCollection = sourceCollection; parentCollection.Remove(droppedItem); droppedItem.ParentFolder = null; (destinationCollection).Add(droppedItem); this.AssociatedObject.ExpandAllHierarchyItems(); } private void MoveItem(Folder droppedItem, Folder targetItem, TreeListViewDropPosition relativeDropPosition) { if (droppedItem == targetItem) return; var parentCollection = this.sourceCollection; parentCollection.Remove(droppedItem); if (relativeDropPosition == TreeListViewDropPosition.Inside) { destinationCollection.Add(droppedItem); } else if (relativeDropPosition == TreeListViewDropPosition.Before) { destinationCollection.Insert(destinationCollection.IndexOf(targetItem), droppedItem); } else if (relativeDropPosition == TreeListViewDropPosition.After) { destinationCollection.Insert(destinationCollection.IndexOf(targetItem) + 1, droppedItem); } this.AssociatedObject.ExpandAllHierarchyItems(); } }0
Ryan
Top achievements
Rank 1
answered on 17 Aug 2016, 08:07 PM
So I figured out something that somewhat emulates the TreeView's DragDrop behavior. I'm using a DragDrop template, which has a ContentPresenter that takes in the screenshot object from the ScreenshotDragVisualProvider().CreateDragVisual(). So I have a preview screenshot of all the nodes being moved, and a preview screenshot of the target node, and I just use the custom template to display the drop position w/the ContentPresenters which show the screenshot visuals.
Thanks for the help,
Ryan
Thanks for the help,
Ryan
0
Hello Ryan,
We already discussed this in the support thread you opened regarding this topic. I will, however, paste my answer here as well, so that it is shared with the community.
In order to customize the appearance of the dragged item, you need to set the DragVisual property of the event arguments of the DragInitialize event handler. It provides the Content and ContentTemplate properties, which you can use to achieve the desired appearance.
Please take a look at the Drag and Drop within RadGridView help topic and the relevant SDK Example, as the approach demonstrated there is applicable to RadTreeListView as well.
All the best,
Stefan X1
Telerik by Progress
We already discussed this in the support thread you opened regarding this topic. I will, however, paste my answer here as well, so that it is shared with the community.
In order to customize the appearance of the dragged item, you need to set the DragVisual property of the event arguments of the DragInitialize event handler. It provides the Content and ContentTemplate properties, which you can use to achieve the desired appearance.
Please take a look at the Drag and Drop within RadGridView help topic and the relevant SDK Example, as the approach demonstrated there is applicable to RadTreeListView as well.
All the best,
Stefan X1
Telerik by Progress
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.