# Drag and Drop

**RadPanorama** handles the whole drag and drop operation by its **TileDragDropService**. The **OnPreviewDragOver** method allows you to control on what targets the tile being dragged can be dropped on. The **OnPreviewDragDrop** method allows you to get a handle on all the aspects of the drag and drop operation, the source (drag) RadPanorama, the destination (target) control, as well as the tile being dragged. This is where the actual physical move of the tile(s) from **RadPanorama** to the target control is performed.

## Drag and Drop functionality between two RadPanorama controls

By default, **RadPanorama** supports drag and drop functionality of the tiles within the same **RadPanorama**. The following example demonstrates a sample approach how to handle the aforementioned events and achieve drag and drop behavior between two **RadPanorama** controls. There is a **TileGroupElement** added to each **RadPanorama**.

![WinForms RadPanorama Drag Drop](https://www.telerik.com/products/winforms/documentation/assets/c4abade4ef9c14ce132fafb9f1a12a52/panorama-drag-and-drop001.gif)

```C#
public class CustomTileDragDropService : TileDragDropService
{
    public CustomTileDragDropService(RadPanoramaElement owner) : base(owner)
    {
    }
 
    RadPanoramaElement draggedParent;
    RadPanoramaElement targetParent;
 
    protected override void OnPreviewDragOver(RadDragOverEventArgs e)
    {
        RadTileElement draggedTile = e.DragInstance as RadTileElement;
        if (draggedTile != null)
        {
            draggedParent = GetTileParent(draggedTile);               
            if (e.HitTarget is RadTileElement)
            {
                targetParent = GetTileParent(e.HitTarget as RadTileElement);
                if (targetParent != draggedParent)
                {
                    e.CanDrop = true;
                }
                else
                {
                    e.CanDrop = false;
                }
            }
            else
            {
                e.CanDrop = false;
            }
        }
    }
 
    private RadPanoramaElement GetTileParent(RadTileElement tile)
    {
        RadElement current = tile.Parent;
        while (current != null)
        {
            if (current is RadPanoramaElement)
            {
                current = current as RadPanoramaElement;
                break;
            }
            current = current.Parent;
        }
        return current as RadPanoramaElement ;
    }
 
    protected override void OnPreviewDragDrop(RadDropEventArgs e)
    {
        e.Handled = true;
        RadTileElement source = this.Context as RadTileElement;
        RadTileElement target = e.HitTarget as RadTileElement;
        TileGroupElement targetGroup = null;
        int insertIndex = 0;
        if (source == null)
        {
            return;
        }
        draggedParent.Items.Remove(source);
       
        if (target != null)
        {
            //groups are available
            if (targetParent.Groups.Count > 0)
            {
                targetGroup = target.Parent.Parent as TileGroupElement;
                insertIndex = targetGroup.Items.IndexOf(target);
            }
            else
            {
                insertIndex = targetParent.Items.IndexOf(target);
            }
            if (insertIndex > -1)
            {
                source.Column = target.Column;
                source.Row = target.Row;
                if (targetGroup != null)
                {
                    targetGroup.Items.Insert(insertIndex, source);
                }
                else
                {
                    targetParent.Items.Insert(insertIndex, source);
                }
            }
        }
        else
        {
            targetParent.Items.Add(source);
        }
 
        if (targetGroup != null)
        {
            AdjustPosition(source, insertIndex, targetGroup.Items);
        }
        else
        {
            AdjustPosition(source, insertIndex, targetParent.Items);
        }
    }
 
    private void AdjustPosition(RadTileElement source, int insertIndex, RadItemOwnerCollection items)
    {
        for (int i = insertIndex + 1; i < items.Count; i++)
        {
            RadTileElement tile = items[i] as RadTileElement;
            if (tile.Row == source.Row && tile.Column >= source.Column && tile != source)
            {
                tile.Column++;
            }
        }
    }
}

```

```VB.NET
Public Class CustomTileDragDropService
    Inherits TileDragDropService
    Public Sub New(owner As RadPanoramaElement)
        MyBase.New(owner)
    End Sub

    Private draggedParent As RadPanoramaElement
    Private targetParent As RadPanoramaElement

    Protected Overrides Sub OnPreviewDragOver(e As RadDragOverEventArgs)
        Dim draggedTile As RadTileElement = TryCast(e.DragInstance, RadTileElement)
        If draggedTile IsNot Nothing Then
            draggedParent = GetTileParent(draggedTile)
            If TypeOf e.HitTarget Is RadTileElement Then
                targetParent = GetTileParent(TryCast(e.HitTarget, RadTileElement))
                If Not targetParent.Equals(draggedParent) Then
                    e.CanDrop = True
                Else
                    e.CanDrop = False
                End If
            Else
                e.CanDrop = False
            End If
        End If
    End Sub

    Private Function GetTileParent(tile As RadTileElement) As RadPanoramaElement
        Dim current As RadElement = tile.Parent
        While current IsNot Nothing
            If TypeOf current Is RadPanoramaElement Then
                current = TryCast(current, RadPanoramaElement)
                Exit While
            End If
            current = current.Parent
        End While
        Return TryCast(current, RadPanoramaElement)
    End Function

    Protected Overrides Sub OnPreviewDragDrop(e As RadDropEventArgs)
        e.Handled = True
        Dim source As RadTileElement = TryCast(Me.Context, RadTileElement)
        Dim target As RadTileElement = TryCast(e.HitTarget, RadTileElement)
        Dim targetGroup As TileGroupElement = Nothing
        Dim insertIndex As Integer = 0
        If source Is Nothing Then
            Return
        End If
        draggedParent.Items.Remove(source)

        If target IsNot Nothing Then
            'groups are available
            If targetParent.Groups.Count > 0 Then
                targetGroup = TryCast(target.Parent.Parent, TileGroupElement)
                insertIndex = targetGroup.Items.IndexOf(target)
            Else
                insertIndex = targetParent.Items.IndexOf(target)
            End If
            If insertIndex > -1 Then
                source.Column = target.Column
                source.Row = target.Row
                If targetGroup IsNot Nothing Then
                    targetGroup.Items.Insert(insertIndex, source)
                Else
                    targetParent.Items.Insert(insertIndex, source)
                End If
            End If
        Else
            targetParent.Items.Add(source)
        End If

        If targetGroup IsNot Nothing Then
            AdjustPosition(source, insertIndex, targetGroup.Items)
        Else
            AdjustPosition(source, insertIndex, targetParent.Items)
        End If
    End Sub

    Private Sub AdjustPosition(source As RadTileElement, insertIndex As Integer, items As RadItemOwnerCollection)
        For i As Integer = insertIndex + 1 To items.Count - 1
            Dim tile As RadTileElement = TryCast(items(i), RadTileElement)
            If tile.Row = source.Row AndAlso tile.Column >= source.Column AndAlso Not tile.Equals(source) Then
                tile.Column += 1
            End If
        Next
    End Sub
End Class

```

In order to replace the default **TileDragDropService** with the default one, it is necessary to set the PanoramaElement.**DragDropService** property:

```C#
radPanorama1.PanoramaElement.DragDropService = new CustomTileDragDropService(radPanorama1.PanoramaElement);
```

```VB.NET
radPanorama1.PanoramaElement.DragDropService = New CustomTileDragDropService(radPanorama1.PanoramaElement)
```

## See Also

* [Structure](https://www.telerik.com/products/winforms/documentation/controls/panorama/structure)
* [Design Time](https://www.telerik.com/products/winforms/documentation/controls/panorama/design-time)
* [Getting Started](https://www.telerik.com/products/winforms/documentation/controls/panorama/getting-started)
* [Properties and Methods ](https://www.telerik.com/products/winforms/documentation/controls/panorama/settings)
* [Tiles](https://www.telerik.com/products/winforms/documentation/controls/panorama/tiles)
