MouseEnter/MouseLeave 和鼠标左键按下

发布于 2024-10-14 11:36:47 字数 370 浏览 6 评论 0原文

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

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

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

现在我已经尝试使用 VisualTreeHelper.HitTest(),但我只知道何时跨越 ListViewItem,并且我需要知道何时离开它。

谢谢。

I'am trying to implement a click and drag selection like the one in windows explorer (the blue selection rectangle that occurs when you keep the mouse button down and you move the mouse).

So basically I have a ListView, with styled and templated ListViewItem.
I have added MouseEnter and MouseLeave event on my ListViewItem (with the EventSetter),
It works fine except when the left mouse button is down.
In this case, the events doesn't get fired, which is not good for what I'm trying to achieve.

Do you know if there is any good workaround for this, I want to know when I'm over an item or not when the left mouse button is down.

For now I've tried with the VisualTreeHelper.HitTest(), but I only know when I cross a ListViewItem, and I need to know when I leave it.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

妳是的陽光 2024-10-21 11:36:47

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

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

You have to capture the mouse UIElement.CaptureMouse when the button is pressed and then release the mouse UIElement.ReleaseMouseCapture during the MouseUp event. You do not have to worry about any other events because all mouse input goes to your UIElement during the capture.

This form of selection is called "lasso select" and most widgets in Windows apps support it. In fact, the ListView itself already does.

梦境 2024-10-21 11:36:47

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

如果您有网格,则需要更复杂的机制,例如跟踪哪个区域被覆盖并检查哪些项目位于内部或边缘。

Even if your MouseEnter and Leave events were fired that would not provide a good method for selection because both events are irrelevant in the end: It does not matter if your mouse ever touched that folder or file, all that matters is if it is in the rectangle at the point in time when you release the button. This means that Mouse Up & Down should be enough. Depending on your list you might even be able to infer which items should be selected just from looking at the two Items on which those events occurred (e.g. if it's just a one-dimensional list as opposed to a two-dimensional grid).

If you have a grid you'd need more complex mechanics like keeping track of which area is covered and checking which items are inside or on the edge.

一袭水袖舞倾城 2024-10-21 11:36:47

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

我已经开始使用这个 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 可以为您提供代表您的对象的矩形,因此我可以检查它是否与选择框矩形相交。

So I have found a different solution to handle this behavior.

I've started, with this stackoverflow answer Click and drag selection box in WPF

In the mouseMove, after modifying the selectionBox size, I select the items that are in the selectionBox region.

I do it this way :

 //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;
 }

I've found that LayoutInformation can gives you the Rect that represent your object, so I can check if it intersect with the selectionBox Rect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文