1

我正在尝试像 Windows 资源管理器中那样实现单击和拖动选择(当您按住鼠标按钮并移动鼠标时出现的蓝色选择矩形)。

所以基本上我有一个 ListView,带有样式和模板化的 ListViewItem。我在我的 ListViewItem 上添加了 MouseEnter 和 MouseLeave 事件(使用 EventSetter),它工作正常,除非鼠标左键按下。在这种情况下,事件不会被触发,这对我想要实现的目标不利。

你知道是否有任何好的解决方法,我想知道当鼠标左键按下时我何时超过一个项目。

现在我已经尝试过使用 VisualTreeHelper.HitTest(),但我只知道什么时候越过 ListViewItem,我需要知道什么时候离开它。

谢谢你。

4

3 回答 3

1

您必须在UIElement.CaptureMouse按下按钮时捕获鼠标,然后UIElement.ReleaseMouseCapture在 MouseUp 事件期间释放鼠标。您不必担心任何其他事件,因为在捕获期间所有鼠标输入都会发送到您的 UIElement。

这种选择形式称为“套索选择”,Windows 应用程序中的大多数小部件都支持它。事实上,ListView 本身已经做到了。

于 2011-01-28T21:54:09.257 回答
0

所以我找到了一种不同的解决方案来处理这种行为。

我已经开始使用这个 stackoverflow 答案在 WPF 中单击并拖动选择框

在 mouseMove 中,修改 selectionBox 大小后,我选择了 selectionBox 区域中的项目。

我这样做:

 //Select all visible items in select region.
 Rect selectRect = new Rect(Canvas.GetLeft(selectionBox), Canvas.GetTop(selectionBox),
                (Canvas.GetLeft(selectionBox) + selectionBox.Width), (Canvas.GetTop(selectionBox) + selectionBox.Height));

 RectangleGeometry rr = new RectangleGeometry(selectRect);
 foreach (CustomElement elt in mainList.Items)
 {
  ListViewItem item = mainList.ItemContainerGenerator.ContainerFromItem(elt) as ListViewItem;
  Rect r = LayoutInformation.GetLayoutSlot(item);
  if (r.IntersectsWith(selectRect))
        item.IsSelected = true;
  else
        item.IsSelected = false;
 }

我发现 LayoutInformation 可以为您提供代表对象的 Rect,因此我可以检查它是否与 selectionBox Rect 相交。

于 2011-01-29T16:52:26.590 回答
0

即使您的 MouseEnter 和 Leave 事件被触发,也不会提供一个好的选择方法,因为这两个事件最终都无关紧要:您的鼠标是否接触过该文件夹或文件并不重要,重要的是它是否在松开按钮时的矩形。这意味着 Mouse Up & Down 应该足够了。根据您的列表,您甚至可以通过查看发生这些事件的两个项目来推断应该选择哪些项目(例如,如果它只是一个一维列表而不是二维网格)。

如果你有一个网格,你需要更复杂的机制,比如跟踪哪个区域被覆盖并检查哪些项目在内部或边缘。

于 2011-01-28T16:02:34.053 回答