Facebook Like Box

Main Menu

Telerik TileViewItem Drag and Drop behavior when one tile is maximized

Most of you are familiar with Telerik controls for WPF. They are no doubt great controls for your application and you can create eye catching and rich GUI desktop application with them. 

TileView is control which provide you functionality to create Tiles in your application. It is quite easy to use and provide rich built in functionalities to fulfill most of your requirements. Drag n Drop behavior is also built in for this control,

but    if you have one tile in maximized mode then Drag n Drop stops working. Ahhh!!!! What if you require DragnDrop for tiles in maximized state as well. I googled and search different blogs and came to know that this functionality is not available in Telerik Controls and they have added it in their PITS. So I decided to implement it myself.

Problem:

Following image will demonstrate the issue.

 Drag and Drop possible in restored state.restored

 

But in following case, it becomes disabled.

maximized

 

 

Solution

I implemented following Behavior to implement above feature.

 

public class RadTilesDragDropBehavior : Behavior
{
    private RadTileViewItem draggingTile { get; set; }
    public TileViewDragDropBehavior()
    {
        // Insert code required on object creation below this point.
    }
    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;
    }
    private void OnDragInitialize(object sender, DragInitializeEventArgs args)
    {
        var tileView = sender as RadTileView;
        var tileViewItem = args.OriginalSource as RadTileViewItem;
        Point pt = Util.CorrectGetPosition((RadTileView)sender);
        HitTestResult result = VisualTreeHelper.HitTest(AssociatedObject, pt);
        if (result != null)
        {
            DependencyObject obj = result.VisualHit.ParentOfType();
            if (obj != null)
            {
                //trying to drag from Tile content area, not allowed.
                return;
            }
        }
        if (tileViewItem != null && tileView != null && tileView.MaximizedItem != null)
        {
            args.Data = tileViewItem;
            var draggingImage = new Image
            {
                Source = new Telerik.Windows.Media.Imaging.RadBitmap(tileViewItem).Bitmap,
                Width = tileViewItem.RestoredWidth,
                Height = tileViewItem.RestoredHeight
            };
            if (tileView.MaximizedItem == tileViewItem)
            {
                args.DragVisualOffset = new Point(args.RelativeStartPoint.X - 50, args.RelativeStartPoint.Y-55);
            }
            args.DragVisual = draggingImage;
            tileViewItem.Opacity = 0;
            args.AllowedEffects = DragDropEffects.Move;
            args.Handled = true;
            // keep a copy of dragging tile
            draggingTile = tileViewItem;
        }
    }
    private void OnDragAndDropCompleted(object sender, DragDropCompletedEventArgs args)
    {
        if (args.OriginalSource.GetType() == typeof(RadTileViewItem))
        {
            if (AssociatedObject.MaximizedItem != null)
            {
                Point pt = Util.CorrectGetPosition((RadTileView)sender);
                HitTestResult result = VisualTreeHelper.HitTest(AssociatedObject, pt);
                if (result != null)
                {
                    DependencyObject obj = result.VisualHit.ParentOfType();
                    if (obj != null)
                    {
                        ((RadTileViewItem)obj).Position = draggingTile.Position;
                        draggingTile.Opacity = 100;
                    }
                    else
                    {
                        draggingTile.Opacity = 100;
                    }
                }
                else
                {
                    draggingTile.Opacity = 100;
                }
            }
        }
    }
    private void MyTileView_PreviewDragOver(object sender, System.Windows.DragEventArgs e)
    {
        FrameworkElement container = sender as FrameworkElement;
        if (AssociatedObject.MaximizedItem != null)
        {
            if (container == null)
            {
                return;
            }
            double tolerance = 60;
            double verticalPos = Util.CorrectGetPosition((RadTileView)container).Y;
            double offset = 20;
            ScrollViewer scrollViewer = AssociatedObject.FindChildByType();
            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;
    }
}
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);
};

This is how you will use it.

 


                    
                        
                    

Have fun!

Add comment


Security code
Refresh