Подтвердить что ты не робот

WPF ListBoxItem двойной щелчок?

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

Можно связать команды с параметрами с ListBoxItem без использования кода или привязанного поведения, просто используя 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, как показано в примере.

Ответ 4

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

<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

Я использовал приведенный выше ответ от Дэвида (который начинается с "Оказывается, есть событие MouseDoubleClick для ListBox." ), чтобы создать решение, основанное на его подходе, но реализованное с приложенным поведением.

Я не говорю, что у вас не будет никакого кода, потому что я знаю, что есть ситуации, когда его не следует избегать за любую цену. Но это еще один пример того, как вы можете преобразовать решение, основанное на событиях, в решение, совместимое с MVVM, которое работает через Event для преобразования привязки команд.

Этот мой код поведения:

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}"
         />