Взаимодействие с мышью у детей ListBoxItem (WPF)
У меня есть ListBox с ItemTemplate, который содержит элемент управления, который взаимодействует с мышью. Это влияет на функциональность выбора ListBox, т. Е. Нажатие элемента управления не выбирает элемент. Это связано с тем, что ListBoxItem устанавливает для свойства Handled события мыши значение true в OnMouseLeftButtonDown. Я попробовал следующее
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
base.OnMouseLeftButtonDown(e);
e.Handled = false;
}
но ListBoxItem "захватывает" мышь и не дает элементу управления выполнять свое собственное взаимодействие. Тогда у меня была другая идея
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
base.OnMouseLeftButtonDown(e);
((ListBoxItem)VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(this)))).IsSelected = true;
}
что на самом деле работает, но больше похоже на уродливый клочок, чем на элегантное решение. Есть ли лучшие решения, которые не зависят от точного содержимого визуального дерева?
3 ответа
Я полагаю, что MouseLeftButtonDown - это событие туннелирования: вы можете попробовать использовать PreviewMouseLeftButtonDown, выполняя там свою обработку, затем обеспечивая e.Handled = false; как вы уже пытались - это должно сработать!
Надеюсь, это поможет.
Я нашел способ, который является менее сложным:
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
base.OnMouseLeftButtonDown(e);
Selector.SetIsSelected(this, true);
}
Чтобы это имело эффект, элементу управления в ItemTemplate ListBox требуется следующий атрибут XAML:
Selector.IsSelected="{Binding IsSelected, Mode=OneWayToSource, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
Это поднимает два новых вопроса:
- Было бы лучше определить мое собственное свойство зависимости, а не находить присоединенное, которое в данный момент не используется?
- Есть ли способ добиться чего-то похожего только в разметке?
Вот одно простое решение, но, к сожалению, обработчик может быть присоединен только в коде, а не в разметке.
Обработчик событий можно добавить с помощью handledEventsToo
подпись AddHandler
метод:
myListBox.AddHandler(UIElement.MouseDownEvent,
new MouseButtonEventHandler(ListBox_MouseDown), true);
Третий параметр выше handledEventsToo
что гарантирует, что этот обработчик будет вызываться независимо от того, отмечен ли он как Handled
(который ListBoxItem
делает в ListBox).
См. Маркировка перенаправленных событий как обработанных и Обработка классов для объяснения.
См. Например, Как Прикрепить к Событию MouseDown на ListBox.