gpt4 book ai didi

c# - 当项目被模板化时如何捕捉 Click on ListboxItem?

转载 作者:行者123 更新时间:2023-11-30 21:19:00 25 4
gpt4 key购买 nike

我有一个设置了 ItemsTemplate 的列表框。

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

我找到了应该给我修改键的 KeyBoard 类。现在如何获取 ListBoxItem 上的点击事件?更好的是,我如何将它绑定(bind)到 ICommand。

我找到了一些点点滴滴,但不知道如何将它们联系起来。看来 InputBinding 似乎可以帮助我或 EventSetter

最佳答案

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

XAML:

<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_PreviewMouseLeftButtonDown"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<s:String>Item1</s:String>
<s:String>Item2</s:String>
<s:String>Item3</s:String>
<s:String>Item4</s:String>
</ListBox>

代码隐藏:

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

要将其绑定(bind)到 ICommand,您可以使用附加行为,如讨论的 EventToCommand 行为 here .

编辑:

针对您的评论,处理 Click 事件对于 ListBoxItem 来说会有点棘手,因为有两件事:1) ListBoxItem 没有点击事件,以及 2) ListBoxItem 在内部处理一些 MouseEvent。不管怎样,我想出了一个模拟的、附加的 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:

<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<EventSetter Event="Loaded" Handler="OnLoaded"/>
</Style>
</ListBox.ItemContainerStyle>
...
</ListBox>

代码隐藏:

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!");
}
}

关于c# - 当项目被模板化时如何捕捉 Click on ListboxItem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3981857/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com