Completed
Last Updated: 08 Jan 2015 09:57 by ADMIN
ADMIN
George
Created on: 06 Feb 2014 11:08
Category: Panorama
Type: Bug Report
0
FIX. RadPanorama - Dropping a tile from one group to another when the group has 1 row and the tile has rowspan 2 exception is thrown
To reproduce:

Add 2 TileGroupElements to a RadPanorama. Set the rowcount of the first to 2 and to the second one to 1. Add a tile to the first group and set its rowspan to 2. Start the application drag the tile, you will see exception.

Workaround:
Create a custom TileDragDropService:

public class MyTileDragDropService : TileDragDropService
{
    private Action<TileGroupElement, RadTileElement, int> OffsetTiles;
    private RadPanoramaElement Owner;

    public MyTileDragDropService(RadPanoramaElement owner)
        : base(owner)
    {
        this.Owner = (RadPanoramaElement)typeof(TileDragDropService).GetField("owner", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this);
        MethodInfo matchedMethod = null;

        foreach (MethodInfo method in typeof(TileDragDropService).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic))
        {
            if (method.Name == "OffsetTiles" && method.GetParameters().Length == 3)
            {
                matchedMethod = method;
                break;
            }
        }

        this.OffsetTiles = (Action<TileGroupElement, RadTileElement, int>)matchedMethod.CreateDelegate(typeof(Action<TileGroupElement, RadTileElement, int>), this);
    }

    protected override void HandleGroupedDragDrop(RadDropEventArgs e)
    {
        RadTileElement target = e.HitTarget as RadTileElement;
        RadTileElement source = this.Context as RadTileElement;
        Point dropLocation = e.DropLocation;

        if (target != null)
        {
            dropLocation = target.PointToControl(dropLocation);
        }

        TileGroupElement @group = GetTargetGroup(new RectangleF(dropLocation, source.Size));
        if (source == null || @group == null)
        {
            return;
        }

        Point targetCell = GetTargetCell(@group, dropLocation);
        if (targetCell.X == -1)
        {
            return;
        }

        targetCell.X = Math.Abs(Math.Min(targetCell.X, @group.RowsCount - source.RowSpan));
        if (targetCell.X >= @group.RowsCount)
        {
            targetCell.X = @group.RowsCount - 1;
        }

        source.Row = targetCell.X;
        source.Column = targetCell.Y;

        if (!@group.Items.Contains(source))
        {
            (source.Parent.Parent as TileGroupElement).Items.Remove(source);
            @group.Items.Add(source);
        }

        int oldColSpan = source.ColSpan;
        source.ColSpan = 0;

        this.OffsetTiles(@group, source, oldColSpan);

        source.ColSpan = oldColSpan;
        source.Column -= oldColSpan;

        this.Owner.InvalidateMeasure(true);
        this.Owner.UpdateLayout();

        return;
    }
}

And set it to the panorama:
panorama.PanoramaElement.DragDropService = new MyTileDragDropService();
0 comments