WPF ListBox没有DoubleClick事件,至少没有我能说的那么多。是否有针对此问题的解决方法,让我双击项目以让事件处理程序对其执行某些操作?谢谢你的帮助。
答案 0 :(得分:34)
事实证明,ListBox有一个MouseDoubleClick事件。我将此事件添加到我的ListBox并让事件处理程序处理我的任务,将所选项目复制到另一个ListBox。所以,现在每当我双击某个项目时,它就会被复制。
答案 1 :(得分:26)
可以将带有参数的命令绑定到ListBoxItem
,而无需使用代码隐藏或附加行为,只需使用InputBindings
即可MouseBinding
,如this answer中所示。
ListBox
的{{1}}示例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>
的{{1}}相同的DataContext中定义,则可以使用示例中包含的ItemsSource
绑定对其进行绑定。
答案 2 :(得分:13)
如果您正在使用数据绑定,那么这个问题很容易解决
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ObjectName}"
MouseDown="TextBlock_MouseDown"/>
</DataTemplate>
</ListBox.ItemTemplate>
然后在您的代码中,检查双击如下
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount>=2)
{
....
}
}
如果在双击之前未选中双击项目,则在事件处理程序中不会显示它。你在那个处理程序中的逻辑需要牢记这一点
答案 3 :(得分:5)
您可以始终覆盖ListItem控件模板并处理模板内的双击事件,例如在包含ListBox正常内容的不可见边框中。
This article shows you how to use a ControlTemplate with a ListBoxItem。除此之外,只需将处理程序添加到控件模板的最外层元素即可。
如果您有Expression Blend,您可以使用它来提取现有的控件模板以供您修改,这样您就不必做太多工作来确保新列表框的行为与旧列表框相同。
答案 4 :(得分:3)
我使用了David的上述答案(以“事实证明ListBox有一个MouseDoubleClick事件”开头)来生成一个基于他的方法的解决方案,但是使用附加行为实现。
我并不是说你不会有任何代码,因为我知道有些情况下不应该以任何代价来避免。但是,这是另一个如何将基于事件的解决方案转换为符合MVVM的解决方案的示例,该解决方案通过事件进行命令绑定转换。
这是我附加的行为代码:
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
}
XAML中的用法:
<ListBox ItemsSource="{Binding CurrentItems}"
behav:DoubleClickSelectorItem.DoubleClickItemCommand="{Binding Path=NavigateDownCommand}"
/>
答案 5 :(得分:1)
ListBox现在有一个双击事件。
答案 6 :(得分:0)
在双击事件上使用:
if (e.OriginalSource.GetType().ToString() == "System.Windows.Controls.TextBlock")
DoubleClickDoneOnItem();
答案 7 :(得分:0)
根据MSDN article,您可以按如下所示将处理程序添加到列表框中的每个项目:
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
然后在后面的代码中处理双击。然后,您可以通过处理程序中的DataContext
来访问sender.DataContext
。由于双击会选择一个项目,因此您还可以在SelectedItem
上使用ListBox
属性或类似属性。
我个人更希望使用Behavior
解决方案,该解决方案允许重定向到命令,但是我不确定如何实现。
答案 8 :(得分:0)
由于我使用的是 SelectionMode="Multiple",因此当前的所有答案都不适用于我,所以我只想与您分享我发现的实现此功能的最简洁的方法。
首先,我为包含的 ListBoxItem 创建了一个处理程序:
public void listBoxItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListBoxItem clickedItem = ((ListBoxItem)sender);
for (int i = 0; i < listBox.Items.Count; i++)
{
if (listBoxECIRatioSizeAutoSelect.Items[i] == clickedItem)
{
doStuff(i);
break;
}
}
}
然后,每当 ListBoxItem 添加到 ListBox 时,Handler 就会添加到 ListBoxItem:
private void addItemToListBox(string strItem)
{
ListBoxItem newItem = new ListBoxItem();
newItem.Content = strItem;
newItem.MouseDoubleClick += listBoxItem_MouseDoubleClick;
listBox.Items.Add(newItem);
}