Mouse interaction in ListBoxItem children (WPF)
I have a ListBox with an ItemTemplate that contains a control that interacts with t开发者_C百科he mouse. This interfers with the selection functionality of the ListBox, i.e. clicking a control does not select the item. This is because ListBoxItem sets the Handled property of the mouse event to true in OnMouseLeftButtonDown. I tried the following
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
base.OnMouseLeftButtonDown(e);
e.Handled = false;
}
but the ListBoxItem “takes over” the mouse and prevents the control from doing its own interaction. Then I had another idea
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
base.OnMouseLeftButtonDown(e);
((ListBoxItem)VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(this)))).IsSelected = true;
}
which actually works, but feels more like an ugly kludge than an elegant solution. Are there any better solutions that don't rely on the exact contents of the visual tree?
I've found a way that is less of a kludge:
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
base.OnMouseLeftButtonDown(e);
Selector.SetIsSelected(this, true);
}
For this to have any effect, the control in the ListBox' ItemTemplate needs the following XAML attribute:
Selector.IsSelected="{Binding IsSelected, Mode=OneWayToSource, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
It raises two new questions:
- Would it be better to define my own dependency property rather than finding an attached one that isn't currently in use?
- Is there a way to achieve something similar in markup only?
I believe the MouseLeftButtonDown is a tunnelling event: you could try using PreviewMouseLeftButtonDown, doing your processing there, then ensuring e.Handled = false; as you tried already - that should do the trick!
Hope that helps.
Here is one simple solution, but unfortunately handler can be attached only in code, not in markup.
Event handler can be added by using handledEventsToo
signature of AddHandler
method:
myListBox.AddHandler(UIElement.MouseDownEvent,
new MouseButtonEventHandler(ListBox_MouseDown), true);
Third parameter above is handledEventsToo
which ensures that this handler will be invoked no matter if it is already marked as Handled
(which ListBoxItem
does in ListBox).
See Marking Routed Events as Handled, and Class Handling for explanation.
See How to Attach to MouseDown Event on ListBox for example.
精彩评论