WPF: responds to the ListViewItem double-click event in the MVVM design. wpfmvvm
The most common event of the ListView control is SelectionChanged. If the MVVM mode is used to design the WPF application, we can usually use behavior (such as InvokeCommandAction) and combined with commands to respond to the event; if we want to respond to the ListViewItem double-click event -- that is, double-click an item in ListView -- what should we do?
First, ListView does not provide related events. Secondly, although ListViewItem has PreviewMouseDoubleClick (Tunnel event), we do not have a suitable method to call in the UI. Is there any way to solve this problem? There must be two solutions. The first method is relatively simple. You can use MouseBinding in DataTemplate. The second method is to add attributes, which is slightly more complex than the first method. Let's look at the Code:
Method 1:
<ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}"> <TextBlock.InputBindings> <MouseBinding Command="{Binding DataContext.ShowInfoCommand, ElementName=window}" MouseAction="LeftDoubleClick" /> </TextBlock.InputBindings> </TextBlock> </DataTemplate></ListView.ItemTemplate>
As you can see, in the above Code, we added the MouseBinding, specified the attribute MouseAction as LeftDoubleClick, and bound its Command attribute to the Command in ViewModel; in this way, you can double-click the current element (TextBlock) with the left button, or double-click the current ListViewItem. Note that the value of the HorizontalContentAlignment attribute of ListViewItem is Left by default. Therefore, TextBlock in the above ememplate is not full of ListViewItem, so you need to add the following style:
<ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> </Style></ListView.ItemContainerStyle>
Method 2:
Create a new class and define an additional Property in it. The Code is as follows:
public class ControlDoubleClick : DependencyObject { public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(ControlDoubleClick), new PropertyMetadata(OnCommandChanged)); public static ICommand GetCommand(Control target) { return (ICommand)target.GetValue(CommandProperty); } public static void SetCommand(Control target, ICommand value) { target.SetValue(CommandProperty, value); } private static void Element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) { Control control = sender as Control; ICommand command = GetCommand(control); if (command.CanExecute(null)) { command.Execute(null); e.Handled = true; } } private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Control control = d as Control; control.PreviewMouseDoubleClick += new MouseButtonEventHandler(Element_PreviewMouseDoubleClick); } }
The Code shows that this method is a real response to the PreviewMouseDoubleClick event of ListViewItem. Next, set the following style for ListViewItem in XAML:
<Window xmlns:behavior="clr-namespace:ListViewItemDoubleClickTest.Behavior" ...> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="behavior:ControlDoubleClick.Command" Value="{Binding DataContext.ShowInfoCommand, ElementName=window}" /> </Style> </ListView.ItemContainerStyle>
Of course, there are more than the above two implementation methods, but they can also be implemented through other methods such as behavior.
Source code download