如何捕获在WPF的列表框上的项目的鼠标点击?(How to capture a mouse clic

2019-06-18 11:10发布

我想它是否已被选中与否,当得到ListBox中的一个项目被用鼠标单击通知。

我搜索,发现这个:( 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
    });
}

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

这工作,但它确实是一个DoubleClick 。 我无法得到它的工作对于单次点击虽然。 我试图MouseLeftButtonDownEvent -因为似乎没有成为一个MouseClick事件,但它不会被调用。

有点更普遍的侧问题:怎样才能看到确实存在哪些事件和处理程序对应于他们,当他们确实做了什么? 例如,什么告诉我,对于一个MouseDoubleClickEvent我需要一个MouseButtonEventHandler ? 也许对于一个MouseLeftButtonDownEvent我需要一些其他的处理程序,这就是为什么它不工作?

我也试着子类ListBoxItem ,并覆盖OnMouseLeftButtonDown -但它不会被调用无论是。

Answer 1:

我相信,你MouseLeftButtonDown处理程序不被调用,因为ListBox使用此事件在内部解雇其SelectionChanged事件(用这种思想是,在绝大多数情况下, SelectionChanged是你所需要的)。 这就是说,你有两个选择。

首先,你可以订阅PreviewLeftButtonDown事件来代替。 大多数路由事件有泡泡的路由策略,这意味着生成事件的控制首先得到它,它不处理该事件的工作它的方式可视化树给每个控制在处理事件的机会。 预览事件,在另一方面,是隧道。 这意味着,他们开始在视觉树(通常的根Window ),并且他们的工作方式,以生成该事件的控制。 由于您的代码会得到前处理该事件的机会ListBoxItem ,这将被解雇(而不是处理),所以您的事件处理程序将被调用。 您可以通过替换实现这个选项MouseDoubleClickEvent与样品中PreviewMouseLeftButtonDown

另一种选择是注册类处理程序,将被通知当一个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 。 如果你点击链接的事件上,它包括该事件的事件处理程序的类型。



Answer 2:

我认为安迪使用的PreviewMouseLeftButtonDown的第一个答案是去了解这个问题的方法。 在XAML它是这样的:

<ListBox Name="testListBox">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBox_MouseLeftButtonDown" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>


Answer 3:

也有另一种方式-来处理PreviewMouseDown事件,并检查它是否是由该列表项触发:

在XAML:

<ListBox PreviewMouseDown="PlaceholdersListBox_OnPreviewMouseDown"/> 

在代码隐藏:

private void PlaceholdersListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var item = ItemsControl.ContainerFromElement(sender as ListBox, e.OriginalSource as DependencyObject) as ListBoxItem;
    if (item != null)
    {
        // ListBox item clicked - do some cool things here
    }
}

灵感来自这个答案,但它的名字使用列表框,我建议使用发件人的说法,以避免不必要的依赖。



Answer 4:

还有另一种方法在ListBox中获得MouseDown事件。 您可以添加事件处理程序通过使用作为处理被标记的事件handledEventsToo的签名AddHandler方法:

myListBox.AddHandler(UIElement.MouseDownEvent, 
        new MouseButtonEventHandler(ListBox_MouseDown), true);

上述第三个参数是handledEventsToo可以确保当此处理程序将被调用,不管它是否已被标记Handled (其中ListBoxItem确实在列表框)。
标识路由事件的处理,类处理的说明。
请参阅如何连接到MouseDown事件的列表框的例子。



Answer 5:

您可以使用SelectionChanged事件的SelectionChangedEventArgs参数查找项目通过AddedItems和RemovedItems添加或删除,通常只有最新的点击,如果没有,再看看这是计数-1的最后一个项目。



Answer 6:

您可以使用Event="MouseLeftButtonUp"
不同于"PreviewLeftButtonDown"它会完成ListBoxItem中处理得。



文章来源: How to capture a mouse click on an Item in a ListBox in WPF?