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

Drag the RadTileViewItem by clicking anywhere on the tile

4 Answers 145 Views
DragAndDrop
This is a migrated thread and some comments may be shown as answers.
dharmesh
Top achievements
Rank 1
dharmesh asked on 17 Mar 2020, 06:44 AM

To make entire tile area draggable, I applied following behavior on RadTileView-

<telerik:RadTileView  IsItemsAnimationEnabled="False"  x:Name="myTileView"
                             ItemsSource="{Binding AvailableChartList,UpdateSourceTrigger=Explicit}" 
                             telerik:RadTileView.ItemContainerStyle="{DynamicResource RadTileViewItemStyle1}"                                  
                             MaximizeMode="Zero">
                    <i:Interaction.Behaviors>
                        <local:RadTilesDragDropBehavior/>
                    </i:Interaction.Behaviors>
</telerik:RadTileView>

-----Behavior------

public class RadTilesDragDropBehavior : Behavior<RadTileView>
{
    private int DragedElementInitialPosition;
    private bool isDragging;
    private int endPosition = -1;
    private RadTileViewItem dragElement;
    protected override void OnAttached()
    {
        base.OnAttached();
        // Insert code that you would want run when the Behavior is attached to an object.        
        DragDropManager.AddDragInitializeHandler(AssociatedObject, OnDragInitialize);
        DragDropManager.AddDragDropCompletedHandler(AssociatedObject, OnDragAndDropCompleted);
        AssociatedObject.PreviewDragOver += MyTileView_PreviewDragOver;
        AssociatedObject.PreviewTilePositionChanged += RadTileView_PreviewTilePositionChanged;
    }
    private void RadTileView_PreviewTilePositionChanged(object sender, Telerik.Windows.RadRoutedEventArgs e)
    {
        if (this.isDragging)
        {
            e.Handled = true;
            var container = e.OriginalSource as RadTileViewItem;
            if (container == this.dragElement)
            {
                this.endPosition = container.Position;
            }
        }
    }
   
    private void OnDragInitialize(object sender, DragInitializeEventArgs args)
    {
        this.isDragging = true;
        var tileView = sender as RadTileView;
        var tileViewItem = args.OriginalSource as RadTileViewItem;
        this.dragElement = tileViewItem;
        this.DragedElementInitialPosition = dragElement.Position;
       
        if (tileViewItem != null && tileView != null)
        {
            args.Data = tileViewItem;
            var draggingItem = new RadTileViewItem
            {
                Style=AssociatedObject.Resources["RadTileViewItemStyle1"] as Style,
                Width = tileViewItem.RestoredWidth,
                Height = tileViewItem.RestoredHeight
            };

            args.DragVisual = draggingItem;
           tileViewItem.Opacity = 100;
           args.AllowedEffects = DragDropEffects.Move;
            args.Handled = true;        
        }
    }

    private void OnDragAndDropCompleted(object sender, DragDropCompletedEventArgs args)
    {
        if (args.OriginalSource.GetType() == typeof(RadTileViewItem))
        {
            this.isDragging = false;
                Point pt = Util.CorrectGetPosition((RadTileView)sender);
                HitTestResult result = VisualTreeHelper.HitTest(AssociatedObject, pt);
                if (result != null)
                {
                    DependencyObject obj = result.VisualHit.ParentOfType<RadTileViewItem>();
                    if (obj != null)
                    {
                        endPosition=((RadTileViewItem)obj).Position;
                        RadTileView parent = args.Source as RadTileView;

                        IEnumerable<RadTileViewItem> itemsToMove = null;

                        if (this.endPosition != -1)
                        {
                            if (this.DragedElementInitialPosition < this.endPosition)
                            {
                                var itemsCollection = ((IList<ChartDetail>)parent.ItemsSource);
                                itemsToMove = itemsCollection
                                     .Select(i => parent.ItemContainerGenerator.ContainerFromItem(i) as RadTileViewItem)
                                     .Where(c => c.Position > this.DragedElementInitialPosition && c.Position <= this.endPosition)
                                     .OrderBy(c => c.Position);

                                foreach (var item in itemsToMove)
                                {
                                    item.Position--;
                                }
                            }
                            else
                            {
                                for (int i = 0; i < this.DragedElementInitialPosition - this.endPosition; i++)
                                {
                                    this.dragElement.Position--;
                                }
                            }
                        }

                        this.endPosition = -1;
                      }
                    else
                    {
                        draggingTile.Opacity = 100;
                    }
                }
                else
                {
                    draggingTile.Opacity = 100;
                }
            }
       }
    
    private void MyTileView_PreviewDragOver(object sender, System.Windows.DragEventArgs e)
    {
        FrameworkElement container = sender as FrameworkElement;
       
            if (container == null)
            {
                return;
            }
            double tolerance = 60;
            double verticalPos = Util.CorrectGetPosition((RadTileView)container).Y;
            double offset = 20;
            ScrollViewer scrollViewer = AssociatedObject.FindChildByType<ScrollViewer>();
            if (verticalPos < tolerance) // Top of visible list?             
            {
                scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - offset); //Scroll up.             
            }
            else if (verticalPos > container.ActualHeight - tolerance) //Bottom of visible list?             
            {
                scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset); //Scroll down.                 
            }       
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        // Insert code that you would want run when the Behavior is removed from an object.      
        DragDropManager.RemoveDragInitializeHandler(AssociatedObject, OnDragInitialize);
        DragDropManager.RemoveDragDropCompletedHandler(AssociatedObject, OnDragAndDropCompleted);
        AssociatedObject.PreviewDragOver -= MyTileView_PreviewDragOver;
        AssociatedObject.PreviewTilePositionChanged -= RadTileView_PreviewTilePositionChanged;
    }

}

If I drag Tile By clicking anywhere on the tile and drop anywhere on the RadTileView, it works fine.

But If I try to drag the Tile by clicking on the header area(RadTileViewItem's default draggable area) and drop the tile out of RadTileView, Tile vanishes from the view. (Please refer the attached image to see the issue.)

Please, suggest a way to fix this issue or if there is any other way to make entire tile draggable.

 

 

4 Answers, 1 is accepted

Sort by
0
Dinko | Tech Support Engineer
Telerik team
answered on 19 Mar 2020, 01:27 PM

Hello Dharmesh,

Thank you for the provided code snippets.

By default, the RadTileViewItem can be dragged by clicking on its header. To start dragging from its content, you will need to create a custom code. I have tested the provided custom implementation on my side, but it seems that a few classes (Util, etc.) are missing. May I ask you to check the attached project and modify it to reproduce this behavior, so I can debug it on my side and think for a possible solution.

Regards,
Dinko
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
dharmesh
Top achievements
Rank 1
answered on 20 Mar 2020, 01:01 PM
In my project, tile is dragged out of tile view by clicking on header, its opacity is becoming 0. I tried to set the opacity of tile in OnDragAndDropCompleted(...), then also it is automatically becoming 0.
I am using NoXaml dlls version 2019.1.220.45.
0
dharmesh
Top achievements
Rank 1
answered on 20 Mar 2020, 01:09 PM

I am not able to upload the modified application.

please, use following Util class in your application-

public static class Util
    {
        public static Point CorrectGetPosition(Visual relativeTo)
        {
            Win32Point w32Mouse = new Win32Point();
            GetCursorPos(ref w32Mouse);
            return relativeTo.PointFromScreen(new Point(w32Mouse.X, w32Mouse.Y));
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct Win32Point
        {
            public Int32 X;
            public Int32 Y;
        };

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetCursorPos(ref Win32Point pt);
    };

 

In your application, drag drop is working fine even if tile is dragged out of tile view by clicking on header.

But in my project, reported issue is reproducible.

 

0
Dinko | Tech Support Engineer
Telerik team
answered on 25 Mar 2020, 08:28 AM

Hello Dharmesh,

Thank you for the provided code snippet. I was able to get it to work, and the custom drag-drop behavior is working as expected. I have added some custom code based on the Drag-drop between GridView and TreeView help article to show custom drag visual element while dragging. You can find the custom project attached to this reply. I am not sure what exactly is not working on your side, but you can check the project and try to modify yours to mimics this implementation.

Regards,
Dinko
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
DragAndDrop
Asked by
dharmesh
Top achievements
Rank 1
Answers by
Dinko | Tech Support Engineer
Telerik team
dharmesh
Top achievements
Rank 1
Share this question
or