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

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

问题描述

我想在ListBox中的项目被鼠标点击时获得通知,无论它是否已被选中。



我搜索并发现: http://kevin-berridge.blogspot.com/ 2008/06 / wpf-listboxitem-double-click.html 查看评论)

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

//用法:
AddDoubleClickEventStyle(listView1,new MouseButtonEventHandler(listView1_MouseDoubleClick));

这种方法适用于 DoubleClick 。我不能得到它工作单击。我试过 MouseLeftButtonDownEvent - 因为似乎没有一个 MouseClick 事件,但它没有被调用。 p>

一个更通用的问题:我如何看到什么事件存在和哪些处理程序对应他们,当他们实际做什么?例如,什么告诉我一个 MouseDoubleClickEvent 我需要一个 MouseButtonEventHandler ?也许为 MouseLeftButtonDownEvent 我需要一些其他处理程序,这就是为什么它不工作?



我也尝试子类化 ListBoxItem 并覆盖 OnMouseLeftButtonDown - 但它也不会被调用。



Marc

解决方案

我相信您的 MouseLeftButtonDown 因为 ListBox 在内部使用此事件触发其 SelectionChanged 事件(考虑到在绝大多数case, SelectionChanged 就是你需要的)。也就是说,您有两个选项。



首先,您可以订阅 PreviewLeftButtonDown 事件。大多数路由事件具有Bubbling的路由策略,这意味着生成该事件的控件首先获得它,并且它不处理该事件在视觉树上向上,使得每个控件有机会处理该事件。另一方面,预览事件是隧道。这意味着它们从视觉树的根部开始(通常 Window ),并向下生成事件的控件。因为你的代码将有机会处理事件之前的 ListBoxItem ,这将被触发(而不是处理),所以你的事件处理程序将被调用。您可以使用 PreviewMouseLeftButtonDown 替换您示例中的 MouseDoubleClickEvent 来实现此选项。



另一个选项是注册一个类处理程序,当 ListBoxItem 触发 MouseLeftButtonDown 事件。这样做:

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

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

类处理器在任何其他事件处理程序之前调用,但是它们在整个应用程序中对所有指定类型的控件调用。因此,如果你有两个 ListBoxes ,那么每当任何 ListBoxItem 被点击时,这个事件处理程序将被调用。



对于你的第二个问题,最好的方式来知道你需要什么类型的事件处理程序,给定的事件,并查看事件的列表给一个给定的控制,就是使用MSDN文档。例如, ListBoxItem 处理的所有事件的列表位于 http://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem_events.aspx 。如果您点击某个事件的链接,它将包含该事件的事件处理程序的类型。


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

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));

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.

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?

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

Marc

解决方案

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.

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 it 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.

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)
{
}

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.

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天全站免登陆