Я считаю, что ваш обработчик 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 . Если вы щелкните ссылку для события, она включает тип обработчика этого события.
ListBoxItem
, находится по адресу http://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem_events.aspx . Если вы щелкнете ссылку для события, в ней будет указан тип обработчика этого события. заключается в использовании документации MSDN. Например, список всех событий, обрабатываемых ListBoxItem
, находится по адресу http://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem_events.aspx . Если вы щелкните ссылку для события, она включает тип обработчика этого события. Я думаю, что первый ответ Энди об использовании PreviewMouseLeftButtonDown - это способ решить эту проблему. В XAML это будет выглядеть так:
<ListBox Name="testListBox">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBox_MouseLeftButtonDown" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Есть другой способ получить событие MouseDown в ListBox. Вы можете добавить обработчик событий для событий, которые помечены как обработанные, используя сигнатуру handledEventsToo
метода AddHandler
:
myListBox.AddHandler(UIElement.MouseDownEvent,
new MouseButtonEventHandler(ListBox_MouseDown), true);
Третий параметр выше - handledEventsToo
, который гарантирует, что это обработчик будет вызываться независимо от того, помечен ли он как Handled
(что делает ListBoxItem
в ListBox).
См. Пометка перенаправленных событий как обработанных и Обработка классов для объяснения.
См., Например, Как присоединиться к событию MouseDown в ListBox .