UWP 拖放自定义 type/class
UWP drag and drop custom type/class
你好,
我正在尝试在 2 个 GridView 之间启用拖放,我设法使用 "DataPackage" class(SetText、SetBitmap 等)的自定义类型来做到这一点,但我无法弄清楚如何使用自定义 class/type 执行此操作。
两个 GridView 都数据绑定到相同的自定义 class(只有几个属性、int、字符串、位图图像),我只是想直接将这些数据项从一个 GridView 拖到另一个。
非常感谢您的帮助!
我遇到了同样的问题,请检查这个示例我使用了 Behaviors,因为我使用了 MVVM 模式,但我为 ListView 做了这个,但对于 GridView 也一样,只是做了一些小的改动。
将行为 <ListView>
更改为 <GridView>
此行为附加在您要拖动项目的 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 模式,只需检查行为的事件。
所以总结一下,为了其他人的利益,我将这些添加到 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);
}
}
你好, 我正在尝试在 2 个 GridView 之间启用拖放,我设法使用 "DataPackage" class(SetText、SetBitmap 等)的自定义类型来做到这一点,但我无法弄清楚如何使用自定义 class/type 执行此操作。 两个 GridView 都数据绑定到相同的自定义 class(只有几个属性、int、字符串、位图图像),我只是想直接将这些数据项从一个 GridView 拖到另一个。 非常感谢您的帮助!
我遇到了同样的问题,请检查这个示例我使用了 Behaviors,因为我使用了 MVVM 模式,但我为 ListView 做了这个,但对于 GridView 也一样,只是做了一些小的改动。
将行为 <ListView>
更改为 <GridView>
此行为附加在您要拖动项目的 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 模式,只需检查行为的事件。
所以总结一下,为了其他人的利益,我将这些添加到 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);
}
}