开发者

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:

  1. Would it be better to define my own dependency property rather than finding an attached one that isn't currently in use?
  2. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜