falukky
falukky

Reputation: 1139

WPF: ListViewIndex from PreviewMouseLeftButtonDown event using command

I want to get index of ListViewIndex from PreviewMouseLeftButtonDown event using command:

<ListView Name="ListViewFiles">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
            <i:InvokeCommandAction Command="{Binding ListViewItemMouseLeftButtonDownCommand}"
                                   CommandParameter="{Binding ElementName=ListViewFiles, Path=SelectedItem}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListView>

Code:

Here i have my ListView and i cannot find a way to get my ListViewItem index or object. I try SelectedItem but its null

public void Execute(object parameter)
{
    var listView = parameter as ListView;
}

Upvotes: 0

Views: 388

Answers (1)

mm8
mm8

Reputation: 169390

PreviewMouseLeftButtonDown is triggered before the item is selected so this approach of using an EventTrigger won't work.

You could hook up an event handler to the MouseLeftButtonDownEvent using the AddHandler method and the handledEventsToo parameter in the code-behind of the view:

ListViewFiles.AddHandler(ListView.MouseLeftButtonDownEvent, new RoutedEventHandler((ss, ee) => 
{
    (DataContext as YourViewModel).ListViewItemMouseLeftButtonDownCommand.Execute(ListViewFiles.SelectedItem);
}), true);

This is not any worse than using an EventTrigger in the XAML markup as far as MVVM is concerned, but if you want to be able to share this functionality across several views, you may create an attached behaviour:

public static class MouseLeftButtonDownBehavior
{
    public static ICommand GetCommand(ListView listView) =>
        (ICommand)listView.GetValue(CommandProperty);

    public static void SetCommand(ListView listView, ICommand value) =>
        listView.SetValue(CommandProperty, value);

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

    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ListView listView = (ListView)d;

        ICommand oldCommand = e.OldValue as ICommand;
        if (oldCommand != null)
            listView.RemoveHandler(UIElement.MouseLeftButtonDownEvent, (MouseButtonEventHandler)OnMouseLeftButtonDown);

        ICommand newCommand = e.NewValue as ICommand;
        if (newCommand != null)
            listView.AddHandler(UIElement.MouseLeftButtonDownEvent, (MouseButtonEventHandler)OnMouseLeftButtonDown, true);
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        ListView listView = (ListView)sender;
        ICommand command = GetCommand(listView);
        if (command != null)
            command.Execute(listView.SelectedItem);
    }
}

XAML:

<ListView Name="ListViewFiles" 
    local:MouseLeftButtonDownBehavior.Command="{Binding ListViewItemMouseLeftButtonDownCommand}" />

Upvotes: 3

Related Questions