我正在尝试实施一个点击和拖动选择,就像在Windows资源管理器中一样(当您按住鼠标按钮并移动鼠标时出现的蓝色选择矩形)。
所以基本上我有一个ListView,带有样式和模板的ListViewItem。 我在ListViewItem上添加了MouseEnter和MouseLeave事件(使用EventSetter), 它工作正常,除非鼠标左键按下。 在这种情况下,事件不会被触发,这对我想要实现的目标不利。
你知道对于这个有没有好的解决方法,我想知道我什么时候在一个项目上,当鼠标左键按下时。
现在我已尝试使用VisualTreeHelper.HitTest(),但我只知道何时越过ListViewItem,我需要知道何时离开它。
谢谢。
答案 0 :(得分:1)
按下按钮时必须捕获鼠标UIElement.CaptureMouse
,然后在MouseUp事件期间释放鼠标UIElement.ReleaseMouseCapture
。您不必担心任何其他事件,因为在捕获期间所有鼠标输入都会转到您的UIElement。
这种选择形式称为“套索选择”,Windows应用程序中的大多数小部件都支持它。实际上,ListView本身已经存在。
答案 1 :(得分:0)
即使您的MouseEnter和Leave事件被触发也无法提供良好的选择方法,因为这两个事件最终都无关紧要:如果您的鼠标曾经触摸过该文件夹或文件并不重要,重要的是它是否是在释放按钮时,它位于矩形中。这意味着Mouse Up&倒是应该够了。根据您的列表,您甚至可以通过查看发生这些事件的两个项目来推断应该选择哪些项目(例如,如果它只是一维列表而不是二维网格)。
如果您有网格,则需要更复杂的机制,例如跟踪覆盖的区域以及检查哪些项目位于内部或边缘。
答案 2 :(得分:0)
所以我找到了一种不同的解决方案来处理这种行为。
我已经开始了,这个stackoverflow回答Click and drag selection box in 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相交。