我是WPF的老用户,但是对WinRT还是陌生的。我想知道是否有一种内置方式或简便方式将交换功能集成到容器中,以便交换可以交换容器中的两个项目。所需的行为是将一个项目拖放到另一个项目上,同时将被拖动的项目和被拖动到的项目都交换在容器中的位置)。
示例我有一个带有1 2 3 4 5 6 7 8的列表,如果我在“ on” 4上拖动7,我希望将两个项目互换,以便结果列表变为1 2 3 7 5 6 4 8
我目前正在将GridView
与ItemsWrapGrid
一起使用,因为它是显示许多图片缩略图的容器。我需要能够通过最常见的操作来重新排序它们,即在两个图像的位置进行交换。
或者,如果没有内置的方式,您能提示我WinRT从头开始执行的“正确”方向吗?我正在考虑不是在容器而是在项目级别处理拖放,并手动交换ObservableCollection
中的项目?
c#大神给出的解决方案
现有的两个答案都将在数据级别为您进行交换。可采取以下措施使UI更加用户友好。
恕我直言,处理交换的最佳UX是,当您拖动一个项目并将其移到另一个项目上时,后者应显示在被拖动项目的原始位置。这清楚地告诉用户项目将准确运往何处。就像下面的gif图片上显示的一样。
为此,您需要创建一个Image
,并在拖动项目移到放置项目上方时使用RenderTargetBitmap
将放置项目的外观复制到其源。当然,当拖动动作开始时,您需要获取拖动项的位置,以便知道将图像放置在何处。
然后,将物品放下后,您应该清除和隐藏图像并进行数据交换。
private void GridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
// get item container, i.e. GridViewItem
var itemContainer = (GridViewItem)this.MyGridView.ContainerFromItem(e.Items[0]);
// get drag item index from its item container
_dragItemIndex = this.MyGridView.IndexFromContainer(itemContainer);
// get drag item position
var position = itemContainer.GetRelativePosition(this.LayoutRoot);
// set the width and height of the image
this.DropItemImage.Width = itemContainer.ActualWidth;
this.DropItemImage.Height = itemContainer.ActualHeight;
// move the image to this location
this.DropItemImage.RenderTransformOrigin = new Point(0, 0);
this.DropItemImage.RenderTransform.Animate(null, position.X, "TranslateX", 0, 0);
this.DropItemImage.RenderTransform.Animate(null, position.Y, "TranslateY", 0, 0);
}
private void GridView_Drop(object sender, DragEventArgs e)
{
// first we need to reset the image
this.DropItemImage.Source = null;
// get the drop & drop items
var dragItem = _groups[_dragItemIndex];
var dropItem = _groups[_dropItemIndex];
// then we swap their positions
_groups.RemoveAt(_dragItemIndex);
_groups.Insert(_dragItemIndex, dropItem);
_groups.RemoveAt(_dropItemIndex);
_groups.Insert(_dropItemIndex, dragItem);
}
private object _previous;
private async void ItemRoot_DragOver(object sender, DragEventArgs e)
{
// first we get the DataContext from the drop item in order to retrieve its container
var vm = ((Grid)sender).DataContext;
// get the item container
var itemContainer = (GridViewItem)this.MyGridView.ContainerFromItem(vm);
// this is just to stop the following code to be called multiple times druing a DragOver
if (_previous != null && _previous == itemContainer)
{
return;
}
_previous = itemContainer;
// get drop item index from its item container
_dropItemIndex = this.MyGridView.IndexFromContainer(itemContainer);
// copy the look of the drop item to an image
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(itemContainer);
this.DropItemImage.Source = bitmap;
// animate the image to make its appearing more interesting
this.DropItemImage.Animate(0, 0.4, "Opacity", 200, 0);
this.DropItemImage.RenderTransformOrigin = new Point(0.5, 0.5);
this.DropItemImage.RenderTransform.Animate(0.8, 1, "ScaleX", 200, 0, new ExponentialEase { EasingMode = EasingMode.EaseIn });
this.DropItemImage.RenderTransform.Animate(0.8, 1, "ScaleY", 200, 0, new ExponentialEase { EasingMode = EasingMode.EaseIn });
}
我提供了一个小的示例项目here,以便您可以查看动画的制作方式。请注意,不包括数据交换部分,正如我所说,其他答案已经很好地说明了这一点。 🙂
当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
Mongo汇总 - javascript我的收藏中有以下文件{ "_id": ObjectId("54490b8104f7142f22ecc97f"), "title": "Sample1", "slug": "samplenews", "cat": …
提交表单后显示模式对话框 - php提交下载文件后,我有一张表格。我要自动而不是自动下载文件..以显示模态对话框并显示下载链接。<form name="softwareform" id="softwareform" action="../downloadlink.php" method="POST" alig…
LeetCode题解计算机为什么是基于二进制的?可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制
LeetCode题解黑白圆盘一个圆盘被涂上了黑白二色,两种颜色各占一个半圆。圆盘以一个未知的速度、按一个未知的方向旋转。你有一种特殊的相机可以让你即时观察到圆上的一个点的颜色。你需要多少个相机才能确定圆盘旋转的方向?题解:可以用一个相机即可