WPF ListBoxItem双击?

WPF ListBoxItem双击?,wpf,wpf-controls,Wpf,Wpf Controls,WPF列表框没有双击事件,至少据我所知不是这样。对于这个问题,是否有一种解决方法可以让我双击某个项目,让事件处理程序对其进行处理?感谢您的帮助。您始终可以覆盖ListItem控件模板,并在模板内处理双击事件,例如在包含ListBox正常内容的不可见边框中 。除此之外,只需将处理程序添加到控件模板的最外层元素 如果您有Expression Blend,您可以使用它提取现有的控件模板进行修改,这样您就不必做太多的工作来确保新列表框的行为与旧列表框相同。事实证明,列表框有一个MouseDoubleCl

WPF列表框没有双击事件,至少据我所知不是这样。对于这个问题,是否有一种解决方法可以让我双击某个项目,让事件处理程序对其进行处理?感谢您的帮助。

您始终可以覆盖ListItem控件模板,并在模板内处理双击事件,例如在包含ListBox正常内容的不可见边框中

。除此之外,只需将处理程序添加到控件模板的最外层元素


如果您有Expression Blend,您可以使用它提取现有的控件模板进行修改,这样您就不必做太多的工作来确保新列表框的行为与旧列表框相同。

事实证明,列表框有一个MouseDoubleClick事件。我将此事件添加到我的列表框中,并让事件处理程序处理我的任务,将所选项目复制到另一个列表框中。所以,现在每当我双击一个项目时,它就会被复制。

如果您使用的是数据绑定,那么这个问题很容易解决

<ListBox.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding ObjectName}"
           MouseDown="TextBlock_MouseDown"/>
    </DataTemplate>
</ListBox.ItemTemplate>    

如果双击项目在双击之前未被选中,则它不会在事件处理程序中显示为选中。您在该处理程序中的逻辑需要记住这一点

我使用了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
}
使用System.Windows;
使用System.Windows.Controls.Primitives;
使用System.Windows.Input;
/// 
///类实现双击
///命令绑定行为。
/// 
公共类双击选择项
{
#区域字段
公共静态只读从属属性DoubleClickItemCommandProperty=
DependencyProperty.RegisterAttached(“DoubleClickItemCommand”,
类型(ICommand),
类型(双击选择项),
新属性元数据(空,
双击SelectorItem.OnDoubleClickItemCommand);
#端域字段
#区域构造函数
/// 
///类构造函数
/// 
公共双击SelectorItem()
{
}
#端域构造函数
#区域属性
#端域属性
#区域方法
#区域附加依赖属性方法
公共静态ICommand GetDoubleClickItemCommand(DependencyObject obj)
{
返回(ICommand)obj.GetValue(DoubleClickItemCommandProperty);
}
公共静态void SetDoubleClickItemCommand(DependencyObject对象、ICommand值)
{
对象设置值(DoubleClickItemCommandProperty,值);
}
#endregion附加的依赖属性方法
私有静态void OnDoubleClickItemCommand(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
var uiElement=d作为选择器;
//删除处理程序(如果存在),以避免内存泄漏
if(uiElement!=null)
uiElement.MouseDoubleClick-=uiElement\u MouseDoubleClick;
var命令=e.NewValue作为ICommand;
if(命令!=null)
{
//属性已附加,因此我们附加Drop事件处理程序
uiElement.MouseDoubleClick+=uiElement\u MouseDoubleClick;
}
}
私有静态void UIElement_MouseDoubleClick(对象发送器,MouseButtonEventArgs e)
{
var uiElement=发送方作为选择器;
//检查是否正常,以防这是由其他人发送的
if(uiElement==null)
返回;
//是否有双击的选定项目?
if(uiElement.SelectedIndex==-1)
返回;
ICommand doubleclickCommand=DoubleClickSelectorItem.GetDoubleClickItemCommand(uiElement);
//毕竟,可能没有绑定到该命令的命令
如果(doubleclickCommand==null)
返回;
//检查此附加行为是否绑定到RoutedCommand
如果(双击命令为路由命令)
{
//执行routed命令
(双击命令作为路由命令)。执行(uiElement.SelectedItem,uiElement);
}
其他的
{
//以绑定委托的形式执行命令
双击命令。执行(uiElement.SelectedItem);
}            
}
#端域法
}
XAML中的用法:

<ListBox ItemsSource="{Binding CurrentItems}"
         behav:DoubleClickSelectorItem.DoubleClickItemCommand="{Binding Path=NavigateDownCommand}"
         />

可以将带有参数的命令绑定到
ListBoxItem
s,而无需使用代码隐藏或附加行为,只需使用带有的
InputBindings
,如中前面所示

示例
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 (e.OriginalSource.GetType().ToString() == "System.Windows.Controls.TextBlock")
     DoubleClickDoneOnItem(); 
根据,您可以向列表框中的每个项目添加处理程序,如下所示:

<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

在后面的代码中,您将处理双击。然后可以通过处理程序中的
sender.DataContext
访问
DataContext
。由于双击选择一个项目,您也可以使用
SelectedItem
属性或
列表框上的类似属性

就个人而言,我更喜欢允许重定向到命令的
行为
解决方案,但我
<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
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;
        }
    }
}
private void addItemToListBox(string strItem)
{
    ListBoxItem newItem = new ListBoxItem();
    newItem.Content = strItem;
    newItem.MouseDoubleClick += listBoxItem_MouseDoubleClick;
    listBox.Items.Add(newItem);
}