如何在 WPF 中的 ListBox 中捕获鼠标单击项目? [英] How to capture a mouse click on an Item in a ListBox in WPF?

查看:30
本文介绍了如何在 WPF 中的 ListBox 中捕获鼠标单击项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在鼠标单击 ListBox 中的项目时收到通知,无论它是否已被选中.

I want to get notified when an item in a ListBox gets clicked by the mouse, whether it is already selected or not.

我搜索并找到了这个:(http:///kevin-berridge.blogspot.com/2008/06/wpf-listboxitem-double-click.html查看评论)

I searched and found this: (http://kevin-berridge.blogspot.com/2008/06/wpf-listboxitem-double-click.html see the comments)

private void AddDoubleClickEventStyle(ListBox listBox, MouseButtonEventHandler mouseButtonEventHandler)
{
    if (listBox.ItemContainerStyle == null)
        listBox.ItemContainerStyle = new Style(typeof(ListBoxItem));
    listBox.ItemContainerStyle.Setters.Add(new EventSetter()
    {
        Event = MouseDoubleClickEvent,
        Handler = mouseButtonEventHandler
    });
}

//Usage:
AddDoubleClickEventStyle(listView1, new MouseButtonEventHandler(listView1_MouseDoubleClick));

这可行,但它适用于 DoubleClick.但是,我无法使其单击一下.我尝试了 MouseLeftButtonDownEvent - 因为似乎没有 MouseClick 事件,但它没有被调用.

This works, but it does it for a DoubleClick. I can't get it working for a single click though. I tried MouseLeftButtonDownEvent - as there doesn't seem to be a MouseClick event, but it's not being called.

一个更笼统的问题:我如何才能看到确实存在哪些事件,哪些处理程序对应于它们以及它们何时实际执行某些操作?例如,什么告诉我对于 MouseDoubleClickEvent 我需要一个 MouseButtonEventHandler?也许对于 MouseLeftButtonDownEvent 我需要一些其他处理程序,这就是它不起作用的原因?

A bit more general side question: How can I see what events do exist and which handlers correspond to them and when they actually do something? For example, what tells me that for a MouseDoubleClickEvent I need a MouseButtonEventHandler? Maybe for a MouseLeftButtonDownEvent I need some other handler and that's why it's not working?

我也尝试子类化 ListBoxItem 并覆盖 OnMouseLeftButtonDown - 但它也没有被调用.

I also tried subclassing ListBoxItem and override OnMouseLeftButtonDown - but it doesn't get called either.

马克

推荐答案

我相信你的 MouseLeftButtonDown 处理程序没有被调用,因为 ListBox 在内部使用这个事件来触发它SelectionChanged 事件(认为在绝大多数情况下,SelectionChanged 就是您所需要的).也就是说,您有几个选择.

I believe that your MouseLeftButtonDown handler is not called because the ListBox uses this event internally to fire its SelectionChanged event (with the thought being that in the vast majority of cases, SelectionChanged is all you need). That said, you have a couple of options.

首先,您可以订阅 PreviewLeftButtonDown 事件.大多数路由事件都有 Bubbling 的路由策略,这意味着生成事件的控件首先获取它,如果不处理,事件会沿着可视化树向上移动,让每个控件都有机会处理事件.另一方面,预览事件是隧道.这意味着它们从可视化树的根(通常是 Window)开始,并一直向下到生成事件的控件.由于您的代码将有机会在 ListBoxItem 之前处理事件,这将被触发(而不是被处理),因此您的事件处理程序将被调用.您可以通过将示例中的 MouseDoubleClickEvent 替换为 PreviewMouseLeftButtonDown 来实现此选项.

First, you could subscribe to the PreviewLeftButtonDown event instead. Most routed events have a routing strategy of Bubbling, which means that the control that generated the event gets it first, and if not handled, the event works its way up the visual tree giving each control a chance at handling the event. The Preview events, on the other hand, are Tunneling. This means that they start at the root of the visual tree (generally Window), and work their way down to the control that generated the event. Since your code would get the chance to handle the event prior to the ListBoxItem, this will get fired (and not be handled) so your event handler will be called. You can implement this option by replacing MouseDoubleClickEvent in your sample with PreviewMouseLeftButtonDown.

另一种选择是注册一个类处理程序,只要 ListBoxItem 触发 MouseLeftButtonDown 事件,就会通知该处理程序.这样做是这样的:

The other option is to register a class handler that will be notified whenever a ListBoxItem fires the MouseLeftButtonDown event. That is done like this:

EventManager.RegisterClassHandler(typeof(ListBoxItem),
    ListBoxItem.MouseLeftButtonDownEvent,
    new RoutedEventHandler(this.MouseLeftButtonDownClassHandler));

private void OnMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
}

类处理程序在任何其他事件处理程序之前被调用,但它们会在整个应用程序中为指定类型的所有控件调用.因此,如果您有两个 ListBoxes,那么只要在其中任何一个中单击任何 ListBoxItem,都会调用此事件处理程序.

Class Handlers are called before any other event handlers, but they're called for all controls of the specified type in your entire application. So if you have two ListBoxes, then whenever any ListBoxItem is clicked in either of them, this event handler will be called.

至于您的第二个问题,了解给定事件所需的事件处理程序类型以及查看给定控件可用的事件列表的最佳方法是使用 MSDN 文档.例如,ListBoxItem 处理的所有事件的列表位于 http://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem_events.aspx.如果您单击某个事件的链接,它会包含该事件的事件处理程序的类型.

As for your second question, the best way to know what type of event handler you need for a given event, and to see the list of events available to a given control, is to use the MSDN documentation. For example, the list of all events handled by ListBoxItem is at http://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem_events.aspx. If you click on the link for an event, it includes the type of the event handler for that event.

这篇关于如何在 WPF 中的 ListBox 中捕获鼠标单击项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆