How do I get the data item of a drop target?

4 posts, 0 answers
  1. Jordan
    Jordan avatar
    12 posts
    Member since:
    Jul 2012

    Posted 27 Oct 2014 Link to this post

    I want to do drag and drop on a RadTreeListView, for example, moving items from one parent node to another. I need to do special handling during the drop operation. For that, I need the underlying data item of that row.

    When I register a handler for, say PreviewDrop, in DragEventArgs, I see OriginalSource is the TextBox, which I assume is the visual UIElement of the drop target. How do I get to the item backed by it in the view model? (The DragInitializeEventArgs.Data gives me a collection of these data items being moved, so I have that).

    Is there something simple I'm missing? Or do I need to climb the visual tree to somehow get to the bound item?
    Thanks!
  2. Boris
    Admin
    Boris avatar
    276 posts

    Posted 30 Oct 2014 Link to this post

    Hi Jordan,

    In order to get the business object for the dragged item, you will need to use the DragDropPayloadManager. For example the OnDrop event handler might look something like the following:
     
    private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
            {
                if (e.Data != null && e.AllowedEffects != DragDropEffects.None)
                {
                    // Get the dragged data (your business object)
                    Collection<Object> payload = DragDropPayloadManager.GetDataFromObject(e.Data, "DragData") as Collection<Object>;
                    if (payload != null)
                    {
                        WarehouseItem droppedItem = (WarehouseItem)payload[0];
                        var destinationRow = e.OriginalSource as TreeListViewRow ?? (e.OriginalSource as FrameworkElement).ParentOfType<TreeListViewRow>();
                        if (destinationRow != null)
                        {
                            WarehouseItem targetItem = destinationRow.DataContext as WarehouseItem;
                            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);
                        }
                    }
                }
            }

    I attached a sample project that demonstrates what i have in mind.

    Please examine it and let us know how it goes.

    Regards,
    Boris Penev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Jordan
    Jordan avatar
    12 posts
    Member since:
    Jul 2012

    Posted 03 Nov 2014 in reply to Boris Link to this post

    Thanks so much for the answer and the example project! One thing I can't figure out: if multiple items are selected and dragged, how do I setup the drag visual? e.OriginalSource seems to be a single item, not a collection.

    For now, I'm creating my own drag visual manually (that is, create my own Label control). Thanks again!
  5. Boris
    Admin
    Boris avatar
    276 posts

    Posted 06 Nov 2014 Link to this post

    Hello Jordan,

    In general dragging and dropping multiple items in RadTreeListView is a complex matter. Since you will need to handle all the cases with removing / adding sub-items from the parent and vise versa. In addition to get the data for the custom DragVisual, you can create a new class that can be filled in the OnDragInitialize() method. There you can pass the data around by using the DragDropPayloadManager.

    In order to customize the DragVisual, you can set its ContentTemplate property to a DataTemplate from your XAML. There you will be able to bind the controls to the properties from your new class (the one you pass to the DragDropPayloadManager). 

    I attached an updated version of my previous project demonstrating a custom DragVisual. Please keep in mind that the project does not handle all the cases, regarding the positioning of the items. 

    I hope this helps.

    Regards,
    Boris
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top