Francesco
Francesco

Reputation: 520

Double left click on listview WPF

I would bind an ICommand on left double click event on item in the ListView. I tried the solution below but doesn't work properly, the Execute function is called when I click the ListView not the item in the list. Someone has any suggestion ?

       <ListView x:Name="history_list_view" HorizontalAlignment="Left" Height="210" Margin="25,194,0,0" 
                  VerticalAlignment="Top" Width="656" Background="#FF2F2B2B" Foreground="White"
                  ItemsSource="{Binding Items}"
                  SelectedItem="{Binding SelectedItem}">
            <ListView.InputBindings >
                <MouseBinding Gesture="LeftDoubleClick" Command="{Binding SelectedItemCommand}" CommandParameter="{Binding SelectedItem}"/>
            </ListView.InputBindings>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#7f8c8d"/>
                            <Setter Property="BorderThickness" Value="0" />
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="#7f8c8d"/>
                            <Setter Property="BorderThickness" Value="0" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView >
                    <GridView.ColumnHeaderContainerStyle>
                        <Style TargetType="{x:Type GridViewColumnHeader}">
                            <Setter Property="HorizontalContentAlignment" Value="Left" />
                        </Style>
                    </GridView.ColumnHeaderContainerStyle>
                    <GridViewColumn Header="Lot" Width="170" DisplayMemberBinding="{Binding Lot}"/>
                    <GridViewColumn Header="Code" Width="160" DisplayMemberBinding="{Binding Code}"/>
                    <GridViewColumn Header="Rev" Width="80" DisplayMemberBinding="{Binding Rev}"/>
                    <GridViewColumn Header="User" Width="140" DisplayMemberBinding="{Binding User}"/>
                    <GridViewColumn Header="Date" Width="100" DisplayMemberBinding="{Binding Date}"/>
                </GridView>
            </ListView.View>
        </ListView>

Upvotes: 0

Views: 295

Answers (2)

BionicCode
BionicCode

Reputation: 28988

Another simple solution is to override the ControlTemplate of the ListBoxItem to set the InputBindings on it:

<ListView>
  <ListView.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <Border Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
              <Border.InputBindings>
                <MouseBinding MouseAction="{x:Static MouseAction.LeftDoubleClick}"
                              Command="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=DataContext.SelectPageCommand}"
                              CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=SelectedItem}" />
              </Border.InputBindings>

              <ContentPresenter />
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </ListView.ItemContainerStyle>
</ListView>

Alternatively turn the complete item into a Button:

<ListView>
  <ListView.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <Button Content="{TemplateBinding Content}" 
                    Command="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=DataContext.SelectedItemCommand}" 
                    CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=SelectedItem}" />
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </ListView.ItemContainerStyle>
</ListView>

You surely want to style the items to remove the button look.

Upvotes: 0

mm8
mm8

Reputation: 169270

Either add an EventSetter for the MouseDoubleClick event in the ItemContainerStyle and invoke the command from the event handler in the code-behind, or use an attached behaviour to execute the command:

public static class DoubleClickBehavior
{
    public static ICommand GetCommand(ListViewItem obj) => (ICommand)obj.GetValue(CommandProperty);

    public static void SetCommand(ListViewItem obj, ICommand value) => obj.SetValue(CommandProperty, value);

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(DoubleClickBehavior), new PropertyMetadata(null, OnCommandChanged));

    private static void OnCommandChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        ListViewItem lvi = (ListViewItem)sender;
        lvi.MouseDoubleClick += Lvi_MouseDoubleClick;
    }

    private static void Lvi_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        ListViewItem lvi = (ListViewItem)sender;
        ICommand command = GetCommand(lvi);
        if (command != null)
            command.Execute(null);
    }
}

XAML:

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="local:DoubleClickBehavior.Command"
                Value="{Binding DataContext.SelectedItemCommand, RelativeSource={RelativeSource AncestorType=ListView}}" />
    </Style>
</ListView.ItemContainerStyle>

Upvotes: 2

Related Questions