Как захватить щелчок мышью по элементу в ListBox в WPF?

Я хочу получать уведомления, когда элемент в ListBox получает щелчок мышью, независимо от того, выбран ли он или нет.

Я искал и нашел это: ( http://kevin-berridge.blogspot.com/2008/06/wpflistboxitem-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 .

Несколько более общий вопрос: как я могу видеть, какие события существуют и какие обработчики соответствуют им и когда они на самом деле что-то делают? Например, что мне подсказывает, что для MouseDoubleClickEvent мне нужен MouseButtonEventHandler ? Может быть, для MouseLeftButtonDownEvent мне нужен какой-то другой обработчик, и поэтому он не работает?

Я также попытался подclassифицировать ListBoxItem и переопределить OnMouseLeftButtonDown – но он также не вызван.

Марк

Я считаю, что ваш обработчик 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.

  • Что означает «Захват мыши» в WPF?
  • Отслеживание положения прокрутки и уведомление об этом других компонентах
  • Подпись к событию в .NET. Использование сильного напечатанного «Отправителя»?
  • Задержка jquery hover event?
  • Использование lambda-выражений для обработчиков событий
  • ActionListener для конкретного текста внутри JTextArea?
  • Мне нужно событие для обнаружения подключения к Интернету / отключения
  • C #: как запросить данные журнала событий с данным идентификатором события?
  • Использование IDisposable для отмены подписки
  • Понимание событий и обработчиков событий в C #
  • Реализация сканера штрих-кода на Java
  • Interesting Posts

    Ограничить подключение SQL Server к определенному IP-адресу

    Держите окно всегда сверху?

    Эффективный алгоритм сжатия коротких текстовых строк

    Не удалось решить: com.google.firebase: firebase-core: 16.0.1

    Восстановить структуру таблицы из файлов frm и ibd

    Строка к двоичной в C #

    Использование селектора «начинается с» для отдельных имен classов

    Не может заимствовать как неизменяемый, поскольку он также заимствован как изменяемый в аргументах функции

    Установить ярлыки для изменения раскладки клавиатуры в Windows 10?

    Можем ли мы увеличить повторное использование этой ключевой схемы защиты доступа?

    Проверка модели Django Unique_together

    Аккумулятор включен или выключен во время работы ноутбука на электричестве?

    Спящий / спящий режим Подтверждение экрана спящего / спящего режима?

    Какие обновления для Windows 7/8 / 8.1 (KBs) я должен пропустить, чтобы избежать обновления Windows 10 и nags?

    Частные внутренние classы в C # – почему они не используются чаще?

    Давайте будем гением компьютера.