Create drag visual without DragInitialize ?

6 posts, 0 answers
  1. Michael
    Michael avatar
    19 posts
    Member since:
    Aug 2014

    Posted 27 Aug 2015 Link to this post

    Hey all.

     I'm playing around with DragDrop behaviours, mainly dragging from other controls (or explorer), and dropping onto a TreeListView. I would like to set the drag visual in these instances (for example, detail how many files are being dragged), but currently, the only way to create a visual is when the item is the source of the drag operation, not the destination.

    Does anyone have any pointers as to where I can go from here ?

  2. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 28 Aug 2015 Link to this post

    Hello,

    You can specify the destination information on DragOver event raised. For the purpose you need to set the DragVisual on DragInitialize and later you update the details on DragOver.
    For example:
    private void OnDragInitialize(object sender, DragInitializeEventArgs e)
    {
        var sourceRow = e.OriginalSource as GridViewRow ?? (e.OriginalSource as FrameworkElement).ParentOfType<GridViewRow>();
        if (sourceRow != null && sourceRow.Name != "PART_RowResizer")
        {
            DropIndicationDetails details = new DropIndicationDetails();
            var item = sourceRow.Item;
            details.CurrentDraggedItem = item;
     
            IDragPayload dragPayload = DragDropPayloadManager.GeneratePayload(null);
     
            dragPayload.SetData("DraggedItem", item);
            dragPayload.SetData("DropDetails", details);
     
            e.Data = dragPayload;
     
            e.DragVisual = new DragVisual()
            {
                Content = details,
                ContentTemplate = this.AssociatedObject.Resources["DraggedItemTemplate"] as DataTemplate
            };
            e.DragVisualOffset = e.RelativeStartPoint;
            e.AllowedEffects = DragDropEffects.All;
        }
    }

    DraggedItemTemplate is defines as follows:
    <telerik:RadGridView.Resources>
        <DataTemplate x:Key="DraggedItemTemplate">
            <StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Dragging:" />
                    <TextBlock Text="{Binding CurrentDraggedItem}"
                       FontWeight="Bold" />
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding CurrentDropPosition}"
                       FontWeight="Bold"
                       MinWidth="45" />
                    <TextBlock Text=", ("
                       Foreground="Gray" />
                    <TextBlock Text="{Binding CurrentDraggedOverItem}" />
                    <TextBlock Text=")"
                       Foreground="Gray" />
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </telerik:RadGridView.Resources>

    DragOver event is raised and handled similarly to:

    private void OnRowDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
    {
        var row = sender as GridViewRow;
        var details = DragDropPayloadManager.GetDataFromObject(e.Data, "DropDetails") as DropIndicationDetails;
     
        if (details == null || row == null)
        {
            return;
        }
     
        details.CurrentDraggedOverItem = row.DataContext;
     
        if (details.CurrentDraggedItem == details.CurrentDraggedOverItem)
        {
            e.Effects = DragDropEffects.None;
            e.Handled = true;
            return;
        }
     
        details.CurrentDropPosition = GetDropPositionFromPoint(e.GetPosition(row), row);       
        int dropIndex = (this.AssociatedObject.Items as IList).IndexOf(row.DataContext);
        int draggedItemIdex = (this.AssociatedObject.Items as IList).IndexOf(DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedItem"));
     
        if (dropIndex >= row.GridViewDataControl.Items.Count - 1 && details.CurrentDropPosition == DropPosition.After)
        {
            details.DropIndex = dropIndex;
            return;
        }
     
        dropIndex = draggedItemIdex > dropIndex ? dropIndex : dropIndex - 1;
        details.DropIndex = details.CurrentDropPosition == DropPosition.Before ? dropIndex : dropIndex + 1;
    }

    A full implementation of such an approach is available on the RowReorder WPF / Silverlight example. In addition, you can check the DragDropManager documentation for more details on how to use it.

    Regards,
    Dimitrina
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
  4. Michael
    Michael avatar
    19 posts
    Member since:
    Aug 2014

    Posted 28 Aug 2015 Link to this post

    Not quite I was after - my scenario is one where I don't have any control over what happens in OnDragInitialize, as the drag is initiated either by a third party control (so DragDropManager.AddDragInitializeHandler(...) won't work), or is initialized by another application (such as dragging files from an explorer window).
  5. Kalin
    Admin
    Kalin avatar
    1207 posts

    Posted 28 Aug 2015 Link to this post

    Hello Michael,

    I'm afraid that without having access to the DragInitilize handler it won't be possible to change the DragVisual during the drag operation. However you can check the following forum thread demonstrating how this can be done if you have access to the DragInitilize handler:
    http://www.telerik.com/forums/change-dragvisual-while-dragging

    If you have any other questions, please do not hesitate to contact us.

    Regards,
    Kalin
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Michael
    Michael avatar
    19 posts
    Member since:
    Aug 2014

    Posted 30 Aug 2015 Link to this post

    Fair enough. I have raised a feature request, so I'll see where that ends up.

    In liu of not being able to change the drag visual, is it possible to get rows the highlight as they do in mouseover events ? My current drop target is a TreeListView, and while dragging over, there is no feedback, which will raise usability issues in the future.

  7. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 01 Sep 2015 Link to this post

    Hi,

    When dragging over, you can update the drag cue on DragOver event raised. Alternatively, you can subscribe to the mouse over event and get the corresponding row using the ParentOfType extension method.
    For example:
    var result = (e.OriginalSource as FrameworkElement).ParentOfType<GridViewRow>();

    Regards,
    Dimitrina
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for WPF is Visual Studio 2017 Ready