在UWP中拖放银行账户列表

我有一个针对本地银行的通用Windows应用程序,我正在进行汇款视图,他们需要使用UWP应用程序中的拖放function从帐户转账到帐户。

我已经制作了动画部分,但是在将列表项放到“帐户到”列表后我需要帮助。

我会附上一个截图来说清楚。 在此处输入图像描述

正如您在图片中看到的,我需要从“来自帐户”列表中拖动一个项目,并将其放在“到帐户”列表中的一个项目上。 我怎样才能做到这一点?

我创建了一个小样本 ,显示了两个ListViews之间的拖放,这些ListViews填充了一些帐户 。 我将跳过UserControls的实现 – 页面xaml看起来像这样:

                              

正如您所看到的,有一个Source列表,其中控件在被拖动时触发事件。

 private void AccountControl_DragStarting(UIElement sender, DragStartingEventArgs args) { if ((sender as AccountControl)?.DataContext is Account account) { args.AllowedOperations = DataPackageOperation.Link; args.Data.SetData(accountId, account.Id); } } 

除了名称和余额之外的Account类具有Guid标识符,因此我可以使用它来传递在转移方法中使用了源帐户的信息。

第二个列表( 目标 )中的项目仅接受放置操作,为此目的,触发两个事件:

 private void AccountControl_DragEnter(object sender, DragEventArgs e) { e.AcceptedOperation = DataPackageOperation.Link; e.DragUIOverride.Caption = "Transfer"; } private async void AccountControl_Drop(object sender, DragEventArgs e) { if ((e.OriginalSource as AccountControl)?.DataContext is Account targetAccount) if (await (e.DataView.GetDataAsync(accountId)) is Guid sourceAccountId) { var sourceAccount = Accounts.First(x => x.Id == sourceAccountId); sourceAccount.Balance -= 1000; targetAccount.Balance += 1000; } } 

第一个设置接受的操作和用户的一些信息。 第二个’将一些钱从一个账户“转移”到第二个账户。

一切看起来像这样:

在此处输入图像描述

您可以直接在MS , 其他文章和MS示例存储库中找到更多帮助。

我对我将提供的“解决方案”并不完全满意。 它们很可能离理想的实现很远,但……

我创建的XAML代码试图轻松复制,但也始终如一地复制您的对象,包含在StackPanel控件内的一组可拖动Rectangles ,以及另一个可以拖动项目的StackPanel控件。

                 Drop anywhere in this area area   

第一解决方案

我将多个Rectangles每个DragStarting事件路由到同一个EventHandler。 在这个EventHandler中,我们可以访问被拖动的UIElement ,因此在Page类中使用UIElement类型的公开属性,您可以简单地克隆必要的属性,以便在需要删除它时,如下所示:

 UIElement dragItem; private void Rectangle_DragStarting(UIElement sender, DragStartingEventArgs args) { dataPackage.RequestedOperation = DataPackageOperation.Copy; dragItem = sender; } 

然后当项目被删除时调用EventHandler,我只需将它添加到我的DropArea中。

  private void StackPanel_Drop(object sender, DragEventArgs e) { Rectangle newElement = new Rectangle(); newElement.Width = (dragItem as Rectangle).Width; newElement.Height = (dragItem as Rectangle).Height; newElement.Fill = (dragItem as Rectangle).Fill; StackPanelDropArea.Children.Add(newElement); } 

您不能通过设置引用要拖动的对象来添加新的控件,因为有一些属性(例如相应的Parent)在您尝试将Control添加到其他容器时会抛出exception。

第二个解决方案:我非常专注于使用DataPackage对象及其支持的默认格式之一,但我认为它们中的任何一个都不能实际保存Object的数据,例如我们的UIElement。

但是每个DataPackage实例都支持一组属性,这些属性对应于Dictionary。 我们可以将Dictionary设置为在那里保存UIElement,只要我们稍后指定一个键来引用同一个对象。

 private void Rectangle_DragStarting(UIElement sender, DragStartingEventArgs args) { dataPackage.RequestedOperation = DataPackageOperation.Copy; args.Data.Properties.Add("myRectangle", sender); } 

在drop事件处理程序中,您可以获取UIElement,如下所示:

 private async void StackPanel_Drop(object sender, DragEventArgs e) { Rectangle element = e.DataView.Properties["myRectangle"] as Rectangle; ...... ...... } 

第三解决方案

此解决方案使用DataPackage公开的方法SetText(String)来保存被拖动的UIElement的Name属性的值。

 private void Rectangle_DragStarting(UIElement sender, DragStartingEventArgs args) { dataPackage = new DataPackage(); dataPackage.RequestedOperation = DataPackageOperation.Copy; Rectangle rectangle = sender as Rectangle; dataPackage.SetText(rectangle.Name); Clipboard.SetContent(dataPackage); } 

通过使用VisualTreeHelper类知道被拖动的UIElementName属性的值,查找它,如下所示:

 private async void StackPanel_Drop(object sender, DragEventArgs e) { DataPackageView dataPackageView = Clipboard.GetContent(); if (dataPackageView.Contains(StandardDataFormats.Text)) { draggedObject = await dataPackageView.GetTextAsync(); } // Dragged objects come from another one of our Parent's Children DependencyObject parent = VisualTreeHelper.GetParent(StackPanelDropArea); int count = VisualTreeHelper.GetChildrenCount(parent); for(int i=0; i< count; i++) { DependencyObject child = VisualTreeHelper.GetChild(parent, i); if(child.GetType().Equals(typeof(StackPanel))) { StackPanel currentStackPanel = child as StackPanel; if(currentStackPanel.Name == "StackPanelRectangles") { int numberOfRectangles = VisualTreeHelper.GetChildrenCount(currentStackPanel); for(int j=0; j 

结果:

在此处输入图像描述

在放弃和使用第三方库之前,我通常会尝试多次处理此问题。 我通常使用的是:

https://github.com/punker76/gong-wpf-dragdrop

您可以在DataTemplate订阅PointerPressed事件并提取您需要的所有内容。

XAML:

     

码:

  private void Grid_OnPointerPressed(object sender, PointerRoutedEventArgs e) { //your FrameworkElement var frameworkElement = sender as FrameworkElement; //global position of your element var itemPosition = frameworkElement.TransformToVisual(Window.Current.Content).TransformPoint(new Point(0, 0)).ToVector2(); //your data var selectedItemData = frameworkElement.DataContext as ItemData; } 

保存您的数据,使用UWP Drag’n’Drop。 在下载加载您的数据。