如何捕获项目模板时单击ListboxItem?

我有一个ListBox与ItemsTemplate集。

现在我想要在ListBoxItem上按Ctrl +左键单击。

我发现KeyBoard类应该给我修饰键。 现在我如何获得ListBoxItem上的click事件? 更好的是,我如何将其绑定到ICommand。

我发现了一些零碎但却不知道如何连接它们。 似乎InputBinding似乎可以帮助我或EventSetter

下面是一个使用ListBoxItem样式中的EventSetter处理Ctrl + PreviewMouseLeftButtonDown的简单示例。 这可能是你想要的。

XAML:

          Item1 Item2 Item3 Item4  

代码隐藏:

 void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) { Console.WriteLine((sender as ListBoxItem).Content.ToString()); e.Handled = false; } } 

要将它绑定到ICommand,您可以使用附加的行为,如此处讨论的EventToCommand行为。

编辑:

为了解决你的评论,处理Click-event对ListBoxItem来说有点棘手,因为有两件事:1)ListBoxItem没有click事件,2)ListBoxItem在内部处理一些MouseEvents。 无论如何,我想出了一个模拟的,附加的ClickEvent来使它工作。 见下文。 希望它有效。

 public class AttachedEvents { private static readonly DependencyProperty IsTriggerEnabledProperty = DependencyProperty.RegisterAttached("IsTriggerEnabled", typeof(bool), typeof(FrameworkElement), new FrameworkPropertyMetadata(false)); public static readonly RoutedEvent ClickEvent; static AttachedEvents() { try { ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(FrameworkElement)); } catch (Exception ex) { } } private static void SetIsTriggerEnabled(FrameworkElement element, bool value) { if (element != null) { element.SetValue(IsTriggerEnabledProperty, value); } } private static bool GetIsTriggerEnabled(FrameworkElement element) { return (element != null) ? (bool)element.GetValue(IsTriggerEnabledProperty) : false; } public static void AddClickHandler(DependencyObject o, RoutedEventHandler handler) { FrameworkElement element = (FrameworkElement)o; element.AddHandler(ClickEvent, handler); element.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(SimulatedClick_MouseLeftButtonUp); element.PreviewMouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(SimulatedClick_MouseLeftButtonDown); } public static void RemoveClickHandler(DependencyObject o, RoutedEventHandler handler) { FrameworkElement element = (FrameworkElement)o; element.RemoveHandler(ClickEvent, handler); element.MouseLeftButtonUp -= new System.Windows.Input.MouseButtonEventHandler(SimulatedClick_MouseLeftButtonUp); element.PreviewMouseLeftButtonDown -= new System.Windows.Input.MouseButtonEventHandler(SimulatedClick_MouseLeftButtonDown); } static void SimulatedClick_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { FrameworkElement element = (FrameworkElement)sender; UpdateIsTriggerSet(element); Mouse.Capture(element); } static void SimulatedClick_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) { FrameworkElement element = (FrameworkElement)sender; bool isTriggerSet = (bool)element.GetValue(IsTriggerEnabledProperty); // update the trigger set flag UpdateIsTriggerSet(element); //release the mouse capture Mouse.Capture(null); // if trigger is set and we are still over the element then we fire the click event if (isTriggerSet && IsMouseOver(element)) { element.RaiseEvent(new RoutedEventArgs(ClickEvent, sender)); } } private static bool IsMouseOver(FrameworkElement element) { Point position = Mouse.PrimaryDevice.GetPosition(element); if (((position.X >= 0.0) && (position.X <= element.ActualWidth)) && ((position.Y >= 0.0) && (position.Y <= element.ActualHeight))) { return true; } else { return false; } } private static void UpdateIsTriggerSet(FrameworkElement element) { Point position = Mouse.PrimaryDevice.GetPosition(element); if (((position.X >= 0.0) && (position.X <= element.ActualWidth)) && ((position.Y >= 0.0) && (position.Y <= element.ActualHeight))) { if (!(bool)element.GetValue(IsTriggerEnabledProperty)) { element.SetValue(IsTriggerEnabledProperty, true); } } else if ((bool)element.GetValue(IsTriggerEnabledProperty)) { element.SetValue(IsTriggerEnabledProperty, false); } } } 

示例用法如下所示。 我似乎无法在XAML中设置附加事件(我不知道为什么)所以我必须在这里做一个解决方法。 我所做的就是等待ListBoxItem加载并在代码隐藏中附加事件处理程序。

XAML:

     ...  

代码隐藏:

 void OnLoaded(object sender, RoutedEventArgs e) { AttachedEvents.AddClickHandler((sender as ListBoxItem), HandleClick); } void HandleClick(object sender, RoutedEventArgs e) { if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) { Console.WriteLine("Ctrl + Clicked!"); } }