如何在GridViewItem
的{{1}}事件中删除OnDrop
索引或位置 ?正如我所读到的,GridView
可以使用GridView.ItemContainerGenerator.ContainerFromItem(item)
ItemContainerGenerator
null
。
这是我目前的代码:
void gridMain_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
var item = e.Items.First();
var source = sender;
e.Data.Properties.Add("item", item);
e.Data.Properties.Add("source", sender);
}
void gridMain_Drop(object sender, DragEventArgs e)
{
var item = e.Data.Properties.Where(p => p.Key == "item").Single();
object source;
e.Data.Properties.TryGetValue("source", out source);
var s = ((GridView)source).ItemContainerGenerator.ContainerFromItem(item);
}
任何提示或建议都会非常有用。
答案 0 :(得分:2)
使用DragEventArgs的GetPosition方法查找项目被删除的位置,然后计算实际索引,请参阅下面的处理程序代码片段。使用此here作为答案(方案3),MSDN example提出了类似问题。
private void GridView_Drop(object sender, DragEventArgs e)
{
GridView view = sender as GridView;
// Get your data
var item = e.Data.Properties.Where(p => p.Key == "item").Single();
//Find the position where item will be dropped in the gridview
Point pos = e.GetPosition(view.ItemsPanelRoot);
//Get the size of one of the list items
GridViewItem gvi = (GridViewItem)view.ContainerFromIndex(0);
double itemHeight = gvi.ActualHeight + gvi.Margin.Top + gvi.Margin.Bottom;
//Determine the index of the item from the item position (assumed all items are the same size)
int index = Math.Min(view.Items.Count - 1, (int)(pos.Y / itemHeight));
// Call your viewmodel with the index and your data.
}
编辑:请将此视为原型。我尝试了它并且它已正常工作,但您可以根据您的方案进行修改(调整延迟超时,立即区分更多TaskCompletionSource等)。
我们的想法是在删除操作后启动任务,以检查项目是仅被删除还是重新排序。
private async void observableCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
object removedItem = e.OldItems[0];
var reorderTask = NoticeReorderAsync(removedItem);
try
{
var task = await Task.WhenAny(reorderTask, Task.Delay(100));
if (reorderTask == task)
{
// removedItem was in fact reordered
Debug.WriteLine("reordered");
}
else
{
TryCancelReorder();
// removedItem was really removed
Debug.WriteLine("removedItem");
}
}
catch (TaskCanceledException ex)
{
Debug.WriteLine("removedItem (from exception)");
}
finally
{
tcs = null;
}
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
object addedItem = e.NewItems[0];
bool added = NoticeAdd(addedItem);
if (added)
{
// addedItem was just added, not reordered
Debug.WriteLine("added");
}
}
}
TaskCompletionSource<object> tcs;
private void TryCancelReorder()
{
if (tcs != null)
{
tcs.TrySetCanceled();
tcs = null;
}
}
private Task NoticeReorderAsync(object removed)
{
TryCancelReorder();
tcs = new TaskCompletionSource<object>(removed);
return tcs.Task;
}
private bool NoticeAdd(object added)
{
if (tcs != null)
{
try
{
if (object.Equals(tcs.Task.AsyncState, added))
{
tcs.TrySetResult(added);
return false;
}
else
{
tcs.TrySetCanceled();
return true;
}
}
finally
{
tcs = null;
}
}
return true;
}