WPF ListBoxItem двойной щелчок? - PullRequest
29 голосов
/ 30 марта 2010

WPF ListBox не имеет события DoubleClick, по крайней мере, насколько я могу судить. Есть ли обходной путь для этой проблемы, который позволил бы мне дважды щелкнуть элемент, чтобы обработчик событий что-то с ним сделал? Спасибо за вашу помощь.

Ответы [ 7 ]

34 голосов
/ 04 апреля 2010

Оказывается, есть событие MouseDoubleClick для ListBox. Я добавил это событие в свой ListBox, и обработчик событий обработал мою задачу, скопировав выбранный элемент в другой ListBox. Так что теперь, когда я дважды щелкаю на предмете, он копируется.

26 голосов
/ 04 ноября 2015

Можно привязать команды с параметрами к ListBoxItem с, не используя code-behind или присоединенные поведения , просто используя InputBindings с MouseBinding, как показано ранее в этот ответ .

Пример 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>

Если команда определена в том же DataContext, что и ItemsSource ListBox, ее можно связать с помощью привязки RelativeSource, как указано в примере.

13 голосов
/ 02 апреля 2012

Если вы используете привязку данных, то эту проблему очень легко решить

<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)
    { 
        ....
    }
}

Если ваш двойной щелчок не был выбран до двойного щелчка, то он не будет отображаться в обработчике событий. Ваша логика в этом обработчике должна помнить об этом

5 голосов
/ 30 марта 2010

Вы всегда можете переопределить шаблон элемента управления ListItem и обработать событие двойного щелчка внутри шаблона, например, в невидимой границе, которая содержит нормальное содержимое ListBox.

В этой статье показано, как использовать ControlTemplate с ListBoxItem . Кроме того, просто добавьте обработчик к самому внешнему элементу вашего шаблона управления.

Если у вас есть Expression Blend, вы можете использовать его для извлечения существующего шаблона элемента управления, который вы можете изменить, чтобы вам не приходилось выполнять слишком много работы, чтобы гарантировать, что новый список работает так же, как старый. *

3 голосов
/ 28 апреля 2014

Я использовал приведенный выше ответ Дэвида (который начинается с «Оказывается, что для 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}"
         />
1 голос
/ 08 июня 2018

ListBox теперь имеет событие двойного щелчка.

0 голосов
/ 25 августа 2018

При использовании события двойного щелчка:

if (e.OriginalSource.GetType().ToString() == "System.Windows.Controls.TextBlock")
     DoubleClickDoneOnItem(); 
...