【发布时间】:2016-03-21 03:08:32
【问题描述】:
我正在 WPF ListBoxes 之间执行拖放操作,我希望能够将其插入到集合中的位置,而不是列表的末尾。
有没有人知道类似于 WinForms ListBox IndexFromPoint 函数的解决方案?
【问题讨论】:
标签: c# wpf wpf-controls
我正在 WPF ListBoxes 之间执行拖放操作,我希望能够将其插入到集合中的位置,而不是列表的末尾。
有没有人知道类似于 WinForms ListBox IndexFromPoint 函数的解决方案?
【问题讨论】:
标签: c# wpf wpf-controls
我最终通过结合使用 DragDropEvent.GetPosition、VisualTreeHelper.GetDescendantBounds 和 Rect.Contains 来完成这项工作。这是我想出的:
int index = -1;
for (int i = 0; i < collection.Count; i++)
{
var lbi = listBox.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
if (lbi == null) continue;
if (IsMouseOverTarget(lbi, e.GetPosition((IInputElement)lbi)))
{
index = i;
break;
}
}
代码位于 ListBox Drop 事件中。 e 对象是传递给 Drop 事件的 DragEventArgs 对象。
IsMouseOverTarget 的实现是:
private static bool IsMouseOverTarget(Visual target, Point point)
{
var bounds = VisualTreeHelper.GetDescendantBounds(target);
return bounds.Contains(point);
}
【讨论】:
你可以使用
itemsControl.InputHitTest(position).
从那里向上走可视化树,直到找到正确的 ItemContainer(对于 ListBox,您会找到 ListBoxItem 等......)
然后调用
itemsControl.ItemContainerGenerator.IndexFromContainer(listBoxItem)
获取插入索引。
【讨论】:
我就是这样做的——迭代列表等没有戏剧性
//Get the position
var currp = e.GetPosition(dgrid);
//Get whats under that position
var elem=dgrid.InputHitTest(currp);
//Your ListView or DataGrid will have set the DataContext to your bound item
if (elem is FrameworkElement && (elem as FrameworkElement).DataContext != null)
{
var target=dgrid.ItemContainerGenerator.ContainerFromItem((elem as FrameworkElement).DataContext)
}
这就是要点 - 然后您可以使用 ItemContainerGenerator.ContainerFromItem 或/和 IndexFromContainer 来获取索引 - 但我怀疑大多数人都想使用 Item
【讨论】: