Взаимодействие с мышью у детей ListBoxItem (WPF) - PullRequest
4 голосов
/ 24 мая 2010

У меня есть ListBox с ItemTemplate, который содержит элемент управления, взаимодействующий с мышью. Это влияет на функциональность выбора ListBox, т. Е. Нажатие элемента управления не выбирает элемент. Это связано с тем, что ListBoxItem устанавливает для свойства Handled события мыши значение true в OnMouseLeftButtonDown. Я попробовал следующее

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
    base.OnMouseLeftButtonDown(e);
    e.Handled = false;
}

но ListBoxItem & ldquo; вступает во владение & rdquo; мышь и препятствует тому, чтобы контроль сделал свое собственное взаимодействие. Тогда у меня была другая идея

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
    base.OnMouseLeftButtonDown(e);
    ((ListBoxItem)VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(this)))).IsSelected = true;
}

, который на самом деле работает, но больше похож на уродливый клудж, чем на элегантное решение. Есть ли лучшие решения, которые не зависят от точного содержимого визуального дерева?

Ответы [ 3 ]

0 голосов
/ 06 июля 2010

Я полагаю, что MouseLeftButtonDown - это событие туннелирования: вы можете попробовать использовать PreviewMouseLeftButtonDown, выполнив там свою обработку, затем обеспечив e.Handled = false;как вы уже попробовали - это должно сработать!

Надеюсь, это поможет.

0 голосов
/ 25 июля 2010

Вот одно простое решение, но, к сожалению, обработчик может быть присоединен только в коде, а не в разметке.
Обработчик событий можно добавить с помощью handledEventsToo подписи AddHandler метода:

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

Третий вышеприведенный параметр - handledEventsToo, который гарантирует, что этот обработчик будет вызываться независимо от того, помечен ли он уже как Handled (что ListBoxItem делает в ListBox).

См. Пометка перенаправленных событий как обработанных и Обработка класса для объяснения.
См. Как присоединить событие MouseDown в ListBox например.

0 голосов
/ 24 мая 2010

Я нашел способ, который меньше клуджа:

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}}}"

Возникает два новых вопроса:

  1. Было бы лучше определить собственное свойство зависимостей, чем находить присоединенное свойство, которое в данный момент не используется?
  2. Есть ли способ добиться чего-то похожего только в разметке?
...