WPF ListBoxItem 双击?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2547442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF ListBoxItem double-click?
提问by David Veeneman
The WPF ListBox doesn't have a DoubleClick event, at least not as far as I can tell. Is there a workaround for this issue that would let me double-click on an item to have an event handler do something with it? Thanks for your help.
WPF ListBox 没有 DoubleClick 事件,至少据我所知没有。是否有解决此问题的方法可以让我双击一个项目让事件处理程序对其进行处理?谢谢你的帮助。
采纳答案by Ben Von Handorf
You could always override the ListItem Control Template and handle the double click event inside the template, for example in an invisible border that contains the normal contents of the ListBox.
您始终可以覆盖 ListItem 控件模板并处理模板内的双击事件,例如在包含 ListBox 正常内容的不可见边框中。
This article shows you how to use a ControlTemplate with a ListBoxItem. Beyond that, simply add the handler to the outermost element of your control template.
本文向您展示了如何将 ControlTemplate 与 ListBoxItem 一起使用。除此之外,只需将处理程序添加到控件模板的最外层元素。
If you have Expression Blend, you can use it to extract the existing control template for you to modify so that you do not have to do as much work to ensure that the new list box behaves the same as the old.
如果您有 Expression Blend,您可以使用它来提取现有的控件模板供您修改,这样您就不必做太多工作来确保新列表框的行为与旧列表框相同。
回答by David Veeneman
It turns out there is a MouseDoubleClick event for the ListBox. I added this event to my ListBox and had the event handler process my task, copying the selected item to another ListBox. So, now whenever I double-click on an item, it gets copied.
结果证明 ListBox 有一个 MouseDoubleClick 事件。我将此事件添加到我的 ListBox 并让事件处理程序处理我的任务,将所选项目复制到另一个 ListBox。所以,现在每当我双击一个项目时,它就会被复制。
回答by marapet
It is possible to bind commands with parameters to ListBoxItem
s without using code-behindor attached behaviors, simply by using InputBindings
with a MouseBinding
, as shown before in this answer.
可以将带有参数的命令绑定到ListBoxItem
s 而不使用代码隐藏或附加行为,只需使用InputBindings
a 即可MouseBinding
,如本答案中所示。
Example ListBox
with MouseBinding
for LeftDoubleClick
:
例如ListBox
与MouseBinding
为LeftDoubleClick
:
<ListBox ItemsSource="{Binding MyDataSource}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MySourceItemName}">
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
CommandParameter="{Binding MySourceItemId}" />
</TextBlock.InputBindings>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If the command is defined in the same DataContext as the ItemsSource
of the ListBox
, it can be bound by using the RelativeSource
binding as included in the example.
如果该命令是在相同的DataContext作为限定ItemsSource
的ListBox
,它可以通过使用结合RelativeSource
作为包括在例如结合。
回答by gls123
If you are using databinding, then this problem is very easy to solve
如果你使用数据绑定,那么这个问题很容易解决
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ObjectName}"
MouseDown="TextBlock_MouseDown"/>
</DataTemplate>
</ListBox.ItemTemplate>
Then in your code behind, check for a double click as follows
然后在你后面的代码中,检查双击如下
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount>=2)
{
....
}
}
If your double clicked item was not selected before the double click, then it wont appear selected in the event handler. Your logic within that handler needs to bear this in mind
如果在双击之前没有选择您的双击项目,则它不会在事件处理程序中显示为选中状态。您在该处理程序中的逻辑需要牢记这一点
回答by user3313608
I have used the above answer from David (which starts with 'It turns out there is a MouseDoubleClick event for the ListBox.') to generate a solution that is based on his approach but is implemented with an attached behavior.
我使用了 David 的上述答案(以“事实证明 ListBox 有一个 MouseDoubleClick 事件”开头)来生成一个基于他的方法但通过附加行为实现的解决方案。
I am not saying you shall not have any code behind because I know there are situations where it should not be avoided for any price. But, this is yet another example of how you can convert an event based solution into an MVVM compliant solution that works via Event to command binding conversion.
我并不是说你不应该有任何代码,因为我知道在某些情况下不应该以任何代价避免它。但是,这是如何将基于事件的解决方案转换为通过事件到命令绑定转换工作的 MVVM 兼容解决方案的另一个示例。
This my attached behavior code:
这是我附加的行为代码:
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
/// <summary>
/// Class implements a <seealso cref="Selector"/> double click
/// to command binding attached behaviour.
/// </summary>
public class DoubleClickSelectorItem
{
#region fields
public static readonly DependencyProperty DoubleClickItemCommandProperty =
DependencyProperty.RegisterAttached("DoubleClickItemCommand",
typeof(ICommand),
typeof(DoubleClickSelectorItem),
new PropertyMetadata(null,
DoubleClickSelectorItem.OnDoubleClickItemCommand));
#endregion fields
#region constructor
/// <summary>
/// Class constructor
/// </summary>
public DoubleClickSelectorItem()
{
}
#endregion constructor
#region properties
#endregion properties
#region methods
#region attached dependency property methods
public static ICommand GetDoubleClickItemCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(DoubleClickItemCommandProperty);
}
public static void SetDoubleClickItemCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(DoubleClickItemCommandProperty, value);
}
#endregion attached dependency property methods
private static void OnDoubleClickItemCommand(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var uiElement = d as Selector;
// Remove the handler if it exist to avoid memory leaks
if (uiElement != null)
uiElement.MouseDoubleClick -= UIElement_MouseDoubleClick;
var command = e.NewValue as ICommand;
if (command != null)
{
// the property is attached so we attach the Drop event handler
uiElement.MouseDoubleClick += UIElement_MouseDoubleClick;
}
}
private static void UIElement_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var uiElement = sender as Selector;
// Sanity check just in case this was somehow send by something else
if (uiElement == null)
return;
// Is there a selected item that was double clicked?
if (uiElement.SelectedIndex == -1)
return;
ICommand doubleclickCommand = DoubleClickSelectorItem.GetDoubleClickItemCommand(uiElement);
// There may not be a command bound to this after all
if (doubleclickCommand == null)
return;
// Check whether this attached behaviour is bound to a RoutedCommand
if (doubleclickCommand is RoutedCommand)
{
// Execute the routed command
(doubleclickCommand as RoutedCommand).Execute(uiElement.SelectedItem, uiElement);
}
else
{
// Execute the Command as bound delegate
doubleclickCommand.Execute(uiElement.SelectedItem);
}
}
#endregion methods
}
Usage in XAML:
XAML 中的用法:
<ListBox ItemsSource="{Binding CurrentItems}"
behav:DoubleClickSelectorItem.DoubleClickItemCommand="{Binding Path=NavigateDownCommand}"
/>
回答by Travis Banger
The ListBox has a double click event now.
ListBox 现在有一个双击事件。
回答by Grunwaldt
On the double-click event use:
在双击事件上使用:
if (e.OriginalSource.GetType().ToString() == "System.Windows.Controls.TextBlock")
DoubleClickDoneOnItem();