2010-05-23 2 views
4

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

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

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

ответ

0

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

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { 
    base.OnMouseLeftButtonDown(e); 
    Selector.SetIsSelected(this, true); 
} 

Для этого, чтобы иметь какой-либо эффект, контроль в ListBox»ItemTemplate необходим следующий атрибут XAML:

Selector.IsSelected="{Binding IsSelected, Mode=OneWayToSource, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" 

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

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

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

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

+0

Благодарим за предложение, но у вас оно есть в обратном порядке: MouseLeftButtonDown - это событие барботирования, а PreviewMouseLeftButtonDown является туннельным. :) Как бы PreviewMouseLeftButtonDown улучшить ситуацию? – absence

+0

Предварительные события происходят до фактических событий: поэтому, если вы сделали свою обработку там, а затем установите e.Handled = false ;, ваш код будет выполнен, но ListBox все равно будет запускать собственный код обработки для изменения выбранного элемента. По крайней мере, надеюсь; вот как я это понимаю! –

0

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

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

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

См. Marking Routed Events as Handled, and Class Handling для пояснения.
См. Например, How to Attach to MouseDown Event on ListBox.

Смежные вопросы