4

我有一个带有 ItemTemplate 的 ListBox,其中包含一个与鼠标交互的控件。这会干扰 ListBox 的选择功能,即单击控件不会选择项目。这是因为 ListBoxItem 在 OnMouseLeftButtonDown 中将鼠标事件的 Handled 属性设置为 true。我尝试了以下

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

这确实有效,但感觉更像是一个丑陋的组合,而不是一个优雅的解决方案。有没有更好的解决方案不依赖于可视化树的确切内容?

4

3 回答 3

0

这是一个简单的解决方案,但不幸的是,处理程序只能附加在代码中,而不是标记中。
可以使用方法handledEventsToo签名添加事件处理程序AddHandler

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

上面的第三个参数handledEventsToo确保无论它是否已经被标记为HandledListBoxItem在 ListBox 中),都会调用这个处理程序。

有关解释,请参阅将路由事件标记为已处理和类处理
例如,请参阅如何附加到 ListBox 上的 MouseDown 事件

于 2010-07-25T14:58:33.480 回答
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. 定义我自己的依赖属性而不是找到当前未使用的附加属性会更好吗?
  2. 有没有办法只在标记中实现类似的东西?
于 2010-05-24T11:26:37.947 回答
0

我相信 MouseLeftButtonDown 是一个隧道事件:您可以尝试使用 PreviewMouseLeftButtonDown,在那里进行处理,然后确保 e.Handled = false; 正如您已经尝试过的那样 - 这应该可以解决问题!

希望有帮助。

于 2010-07-06T12:16:27.697 回答