WPF ListBoxには、少なくとも私が知る限りでは、DoubleClickイベントがありません。この問題の回避策として、アイテムをダブルクリックしてイベントハンドラーで何かを実行させる方法はありますか?ご協力いただきありがとうございます。
ListItemコントロールテンプレートを常にオーバーライドし、テンプレート内のダブルクリックイベントを処理できます。たとえば、ListBoxの通常のコンテンツを含む非表示の境界線で処理できます。
この記事では、ListBoxItemでControlTemplateを使用する方法を示します 。さらに、ハンドラーをコントロールテンプレートの最も外側の要素に追加するだけです。
Expression Blendがある場合は、それを使用して既存のコントロールテンプレートを抽出し、変更して、新しいリストボックスが古いリストボックスと同じように動作することを確認するために必要な作業を減らすことができます。
ListBoxのMouseDoubleClickイベントがあることがわかります。このイベントをリストボックスに追加し、イベントハンドラーでタスクを処理して、選択したアイテムを別のリストボックスにコピーしました。したがって、アイテムをダブルクリックするたびに、コピーされます。
code-behindまたは付属の動作を使用せずに、パラメーターを指定したコマンドをListBoxItem
sにバインドすることができます。 InputBindings
でMouseBinding
を使用すると、 この答え 。
例ListBox
とMouseBinding
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>
コマンドがItemsSource
のListBox
と同じDataContextで定義されている場合、例に含まれているRelativeSource
バインディングを使用してバインドできます。
データバインディングを使用している場合、この問題は非常に簡単に解決できます
<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)
{
....
}
}
ダブルクリックする前にダブルクリックしたアイテムが選択されていなかった場合、そのアイテムはイベントハンドラーで選択された状態で表示されません。そのハンドラ内のロジックは、これを念頭に置く必要があります
私は、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}"
/>
ListBoxにダブルクリックイベントが追加されました。
ダブルクリックイベントを使用する場合:
if (e.OriginalSource.GetType().ToString() == "System.Windows.Controls.TextBlock")
DoubleClickDoneOnItem();