Как захватить щелчок мышью по элементу в ListBox в WPF?
Я хочу получать уведомления, когда элемент в 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
, но оно не MouseClick
.
- Каковы различия между делегатами и событиями?
- Определите, будет ли пользователь щелкать полосу прокрутки или содержимое (onclick для собственной полосы прокрутки)
- Событие изменения триггера () при установке значения с помощью функции val ()
- Как удалить все обработчики событий из события
- Мышь родительского контроля Ввод / выключение событий с помощью детского контроля
Несколько более общий вопрос: как я могу видеть, какие события существуют и какие обработчики соответствуют им и когда они на самом деле что-то делают? Например, что мне подсказывает, что для MouseDoubleClickEvent
мне нужен MouseButtonEventHandler
? Может быть, для MouseLeftButtonDownEvent
мне нужен какой-то другой обработчик, и поэтому он не работает?
Я также попытался подclassифицировать ListBoxItem
и переопределить OnMouseLeftButtonDown
– но он также не вызван.
Марк
- Как добавить событие в UserControl в C #?
- Почему события не могут использоваться одинаково в производных classах, как в базовом classе в C #?
- Остановить распространение событий мыши в угловом
- iOS - нажимать вперед все
- jquery Event.stopPropagation (), похоже, не работает
- Как обеспечить, чтобы событие было подписано только один раз
- Как проверить, была ли клавиша нажата клавишей со стрелкой в Java KeyListener?
- Как распознать события касания, используя jQuery в Safari для iPad? Является ли это возможным?
Я считаю, что ваш обработчик MouseLeftButtonDown
не вызывается, потому что ListBox
использует это событие внутри, чтобы запустить его событие SelectionChanged
(с мыслью, что в подавляющем большинстве случаев SelectionChanged
– это все, что вам нужно). Тем не менее, у вас есть несколько вариантов.
Во-первых, вы могли бы подписаться на событие PreviewLeftButtonDown
. Большинство маршрутизируемых событий имеют страtagsю маршрутизации Bubbling, а это означает, что элемент управления, сгенерировавший это событие, получает его первым, и он не обрабатывает событие, которое проходит путь к визуальному дереву, дающему каждому управляющему шанс обработать событие. С другой стороны, событиями предварительного просмотра являются туннелирование. Это означает, что они начинаются с корня визуального дерева (как правило, Window
) и работают до элемента управления, создавшего событие. Так как ваш код получит возможность обработать событие до ListBoxItem
, это будет ListBoxItem
(и не будет обработано), поэтому ваш обработчик событий будет вызван. Вы можете реализовать эту опцию, заменив MouseDoubleClickEvent
в вашем примере на PreviewMouseLeftButtonDown
.
Другой вариант – зарегистрировать обработчик classа, который будет уведомляться всякий раз, когда ListBoxItem
запускает событие MouseLeftButtonDown
. Это делается следующим образом:
EventManager.RegisterClassHandler(typeof(ListBoxItem), ListBoxItem.MouseLeftButtonDownEvent, new RoutedEventHandler(this.MouseLeftButtonDownClassHandler)); private void OnMouseLeftButtonDown(object sender, RoutedEventArgs e) { }
Обработчики classов вызываются перед любыми другими обработчиками событий, но они вызываются для всех элементов управления указанного типа во всем приложении. Поэтому, если у вас есть два ListBoxes
, тогда всякий раз, когда в любой из них будет нажата любая ListBoxItem
, этот обработчик событий будет вызван.
Что касается вашего второго вопроса, лучший способ узнать, какой тип обработчика событий вам нужен для данного события, а также просмотреть список событий, доступных для данного элемента управления, – это использовать документацию MSDN. Например, список всех событий, обрабатываемых ListBoxItem
находится по адресу http://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem_events.aspx . Если вы нажмете на ссылку для события, она включает в себя тип обработчика события для этого события.
Я думаю, что первым ответом Энди на использование PreviewMouseLeftButtonDown является способ этого. В XAML это будет выглядеть так:
Существует и другой способ – обработать событие PreviewMouseDown
и проверить, был ли он вызван элементом списка:
В XAML:
В коде:
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 } }
Был вдохновлен этим ответом, но он использует listbox по имени, я предлагаю использовать аргумент отправителя, чтобы избежать ненужных зависимостей.
Есть еще один способ получить событие MouseDown в ListBox. Вы можете добавить обработчик событий для событий, отмеченных как обработанные с помощью handledEventsToo
подписи метода AddHandler
:
myListBox.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(ListBox_MouseDown), true);
Третий параметр выше handledEventsToo
который гарантирует, что этот обработчик будет вызван независимо от того, уже ли он отмечен как Handled
(какой ListBoxItem
делает в ListBox).
См. Раздел « Маркировка маршрутизированных событий как обработанных» и «Обработка classов» для объяснения.
См., Например, « Присоединение к событию MouseDown» в ListBox .
Вы можете использовать аргумент SelectionChangedEventArgs события SelectionChanged, чтобы узнать, какой элемент добавляется или удаляется с помощью AddItems и RemovedItems, как правило, только последнее нажатие, или если нет, то посмотрите на последний элемент, который является счетчиком-1.
Вы можете использовать Event="MouseLeftButtonUp"
В отличие от "PreviewLeftButtonDown"
он также обрабатывает ListBoxItem.