【问题标题】:UWP drag and drop custom type/classUWP 拖放自定义类型/类
【发布时间】:2016-03-11 00:26:46
【问题描述】:

你好, 我正在尝试在 2 个 GridView 之间启用拖放,我设法使用“DataPackage”类(SetText、SetBitmap 等)的自定义类型来做到这一点,但我不知道如何使用自定义类/类型。 两个 GridView 数据绑定到同一个自定义类(只有几个属性,int、string、bitmapimage),我只是想直接将这些数据项从一个 GridView 拖到另一个。 非常感谢您的帮助!

【问题讨论】:

    标签: c# drag-and-drop win-universal-app


    【解决方案1】:

    所以总结一下,为了其他人的利益,我将这些添加到 DataTemplate 内容的事件处理程序中,因为我只希望某个 (ViewModel) 类型的项目是可拖动的。

        private void Grid_Drop(object sender, DragEventArgs e)
        {
            if (sender is FrameworkElement)
            {
                var fe = sender as FrameworkElement;
                var targetIvm = fe.DataContext as ItemViewModel;
                object obj = null;
                if(e.DataView.Properties.TryGetValue("ItemViewModel", out obj))
                {
                    var sourceIvm = obj as ItemViewModel;
                    vm.MoveItem(sourceIvm, targetIvm);
                }
            }
        }
    
        private void Grid_DragStarting(Windows.UI.Xaml.UIElement sender, DragStartingEventArgs args)
        {
            if (sender is FrameworkElement)
            {
                var fe = sender as FrameworkElement;
                var item = new KeyValuePair<string, object>("ItemViewModel", fe.DataContext);
                args.Data.RequestedOperation = DataPackageOperation.Move;
                args.Data.Properties.Add("ItemViewModel", fe.DataContext);
            }
        }
    

    【讨论】:

    • 这很有帮助,你知道如何找出插入点吗?我的 GridView 是 CanReorderItems,因此它可以放置一个空间,但是在 Drop() 期间,我只设法从一个 ObservableCollection 中删除并添加到另一个。 (我有三个单独的 GridView,但我可以尝试使用组中的一个......)
    【解决方案2】:

    我遇到了同样的问题,请查看这个示例,因为我使用了 MVVM 模式,所以我使用了 MVVM 模式,但我对 ListView 执行了此操作,但对 GridView 也是如此,只是做了一些小改动。

    将行为 &lt;ListView&gt; 更改为 &lt;GridView&gt;

    此行为附加在要拖动项目的 ListView 中

    public class StartingDragBehavior:Behavior<ListView>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.CanDragItems = true;
            this.AssociatedObject.DragItemsStarting += AssociatedObject_DragItemsStarting;
        }
    
    
        private void AssociatedObject_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
        {
            e.Data.RequestedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
            if(e.Items!=null && e.Items.Any())
            {
                e.Data.Properties.Add("item", e.Items.FirstOrDefault());
    
            }
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.DragItemsStarting -= AssociatedObject_DragItemsStarting;
    
        }
    }
    

    此行为附加在您要放置项目的 ListView 中 这里有另一个 Behavior 来捕获 drop 事件。

    public class EndDropBehavior : Behavior<ListView>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.AllowDrop = true;
            this.AssociatedObject.Drop += AssociatedObject_Drop;
            this.AssociatedObject.DragOver += AssociatedObject_DragOver;
        }
    
        private void AssociatedObject_Drop(object sender, Windows.UI.Xaml.DragEventArgs e)
        {
            if (e.DataView != null &&
                e.DataView.Properties != null &&
                e.DataView.Properties.Any(x => x.Key == "item" && x.Value.GetType() == typeof(MyObject)))
            {
                try
                {
                    var def = e.GetDeferral();
    
                    var item = e.Data.Properties.FirstOrDefault(x => x.Key == "item");
                    var card = item.Value as MyObject;
    
    
                        var list = sender as ListView;
                        var vm = list.DataContext as Infrastructure.ViewModels.CreditCardsViewModel;
    
    
                            vm.MyCollection.Add(card);
    
                    def.Complete();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
    
                }
    
            }
            else
            {
                e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.None;
            }
        }
    
        private void AssociatedObject_DragOver(object sender, Windows.UI.Xaml.DragEventArgs e)
        {
            if (e.DataView != null &&
                e.DataView.Properties != null &&
                e.DataView.Properties.Any(x => x.Key == "item" && x.Value.GetType() == typeof(MyObject)))
            {
    
                e.AcceptedOperation = e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
    
            }
            else
            {
                e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.None;
            }
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.Drop -= AssociatedObject_Drop;
    
            this.AssociatedObject.DragOver -= AssociatedObject_DragOver;
        }
    }
    

    如果您不使用 MVVM 模式,只需检查 to Behaviors 的事件。

    【讨论】:

    • 谢谢 Riccardo,您的回答为我指明了正确的方向:“e.Data.Properties.Add”允许我将自定义类型添加为属性并使用“e.Data.Properties.TryGetValue” ()" 您会得到一个对象,然后您可以将其转换为您的自定义类型。效果很好!
    • 这对我有帮助,谢谢!唯一的区别是我需要使用 e.DataView.Properties.TryGetValue() ...
    猜你喜欢
    • 2019-06-10
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多