web-dev-qa-db-ja.com

WPF ListBoxItemをダブルクリックしますか?

WPF ListBoxには、少なくとも私が知る限りでは、DoubleClickイベントがありません。この問題の回避策として、アイテムをダブルクリックしてイベントハンドラーで何かを実行させる方法はありますか?ご協力いただきありがとうございます。

30
David Veeneman

ListItemコントロールテンプレートを常にオーバーライドし、テンプレート内のダブルクリックイベントを処理できます。たとえば、ListBoxの通常のコンテンツを含む非表示の境界線で処理できます。

この記事では、ListBoxItemでControlTemplateを使用する方法を示します 。さらに、ハンドラーをコントロールテンプレートの最も外側の要素に追加するだけです。

Expression Blendがある場合は、それを使用して既存のコントロールテンプレートを抽出し、変更して、新しいリストボックスが古いリストボックスと同じように動作することを確認するために必要な作業を減らすことができます。

5
Ben Von Handorf

ListBoxのMouseDoubleClickイベントがあることがわかります。このイベントをリストボックスに追加し、イベントハンドラーでタスクを処理して、選択したアイテムを別のリストボックスにコピーしました。したがって、アイテムをダブルクリックするたびに、コピーされます。

35
David Veeneman

code-behindまたは付属の動作を使用せずに、パラメーターを指定したコマンドをListBoxItemsにバインドすることができます。 InputBindingsMouseBindingを使用すると、 この答え

ListBoxMouseBinding with 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>

コマンドがItemsSourceListBoxと同じDataContextで定義されている場合、例に含まれているRelativeSourceバインディングを使用してバインドできます。

29
marapet

データバインディングを使用している場合、この問題は非常に簡単に解決できます

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

ダブルクリックする前にダブルクリックしたアイテムが選択されていなかった場合、そのアイテムはイベントハンドラーで選択された状態で表示されません。そのハンドラ内のロジックは、これを念頭に置く必要があります

13
gls123

私は、Davidからの上記の回答(「ListBoxのMouseDoubleClickイベントがあることがわかりました」で始まる)を使用して、彼のアプローチに基づいたソリューションを生成しましたが、動作は添付されています。

私はあなたがコードを避けてはならないということを言っているのではありません。ただし、これは、イベントベースのソリューションを、イベントからコマンドバインディングへの変換を介して機能するMVVM準拠のソリューションに変換する方法のもう1つの例です。

これは私の添付された動作コードです:

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

ListBoxにダブルクリックイベントが追加されました。

1
Travis Banger

ダブルクリックイベントを使用する場合:

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