如何捕获鼠标点击WPF中ListBox中的项目? [英] How to capture a mouse click on an Item in a ListBox in WPF?
问题描述
我搜索并发现:() http://kevin-berridge.blogspot.com/2008 /06/wpf-listboxitem-double-click.html 查看评论)
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
});
}
//用法:
AddDoubleClickEventStyle(listView1,new MouseButtonEventHandler(listView1_MouseDoubleClick));
这是有效的,但它为 DoubleClick
。我无法让它单击一下。我尝试 MouseLeftButtonDownEvent
- 因为似乎没有一个 MouseClick
事件,但它没有被调用。 p>
有一个更普遍的一个问题:我如何看到事件确实存在,以及哪些处理程序与它们对应,何时实际执行某些操作?例如,告诉我,对于一个 MouseDoubleClickEvent
我需要一个 MouseButtonEventHandler
?可能是一个 MouseLeftButtonDownEvent
我需要一些其他处理程序,这就是为什么它不工作?
我也尝试子类化 ListBoxItem
并覆盖 OnMouseLeftButtonDown
- 但它也不会被调用。
Marc
我相信你的 MouseLeftButtonDown
因为 ListBox
在内部使用此事件来触发其 SelectionChanged
事件(以为绝大多数案例, SelectionChanged
是你需要的)。也就是说,你有几个选择。
首先,你可以订阅 PreviewLeftButtonDown
事件。大多数路由事件都有一个冒泡的路由策略,这意味着生成该事件的控件首先得到它,并且它不处理该事件的方式,直到视觉树给每个控件一个处理事件的机会。另一方面,预览事件是隧道。这意味着它们从视觉树的根目录开始(通常为 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屋!