RadTileViewItem以最小化状态拖放

时间:2013-03-05 10:35:04

标签: wpf drag-and-drop telerik tiles

我在我的项目中使用RadTileView,默认情况下,当Tile拖放处于恢复状态时启用

as in figure 1

但是当1个磁贴处于最大化状态而所有其他磁贴处于最小化状态时,我无法实现相同的功能

as in figure 2

我认为Telerik没有在RadTileView控件中提供此功能。实现这一目标的最佳方式是什么,或者是否可能?

1 个答案:

答案 0 :(得分:1)

搜索完不同的博客后,我发现Telerik Tile视图中没有提供此功能,但他们已将其添加到愿望清单中。您可以在此投票赞助此功能http://www.telerik.com/support/pits.aspx#/public/silverlight/2449

然而,作为一项工作,我已经为RadTileView实现了一个行为,它将完成所需的任务。

public class RadTilesDragDropBehavior : Behavior<RadTileView>
{
    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<RadFluidContentControl>();
            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<RadTileViewItem>();
                    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<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;
    }

}



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);
};

XAML会是这样的

<telerik:RadTileView  x:Name="MyTileView" ItemsSource={Binding TileItems}>
                    <i:Interaction.Behaviors>
                        <behaviors:RadTilesDragDropBehavior/>
                    </i:Interaction.Behaviors>
</telerik:RadTileView>