GridView DoubleClick
Asked Answered
E

3

4

I have a GridView where I want to detect a doubleclick event on the items in the list, i do it as follows:

<ListView>
    <ListView.View >
        <GridView >
            <GridViewColumn Header="FileName">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Label Content="{Binding FileName}" MouseDoubleClick="Configuration_MouseDoubleClick"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding CreationDate}" Header="Date"/>
        </GridView>
     </ListView.View>
</ListView>

The problem is that I can only detect doubleclicks by attaching it to the control in the template.

How can I attach the MouseDoubleClick event to the whole ListViewItem? Is there any solution for that with PRISM?

Edington answered 5/12, 2010 at 20:34 Comment(0)
P
16

You can add the MouseDoubleClick event to ListViewItem in the ItemContainerStyle like this

<ListView ...>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

Code behind..

void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    //...            
}
Policlinic answered 5/12, 2010 at 20:42 Comment(0)
M
15

If you're doing MVVM, you can bridge the gap between codebehind and your viewmodel the usual way--by using an attached behavior:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

public sealed class HandleDoubleClickBehavior
{
    public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached(
        "Command", typeof (ICommand), typeof (HandleDoubleClickBehavior), new PropertyMetadata(default(ICommand), OnComandChanged));

    public static void SetCommand(DependencyObject element, ICommand value)
    {
        element.SetValue(CommandProperty, value);
    }

    public static ICommand GetCommand(DependencyObject element)
    {
        return (ICommand) element.GetValue(CommandProperty);
    }

    public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.RegisterAttached(
        "CommandParameter", typeof (object), typeof (HandleDoubleClickBehavior), new PropertyMetadata(default(object)));

    public static void SetCommandParameter(DependencyObject element, object value)
    {
        element.SetValue(CommandParameterProperty, value);
    }

    public static object GetCommandParameter(DependencyObject element)
    {
        return (object) element.GetValue(CommandParameterProperty);
    }

    private static void OnComandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var c = d as Control;
        if (c == null)
            throw new InvalidOperationException($"can only be attached to {nameof(Control)}");
        c.MouseDoubleClick -= OnDoubleClick;
        if (GetCommand(c) != null)
            c.MouseDoubleClick += OnDoubleClick;
    }

    private static void OnDoubleClick(object sender, MouseButtonEventArgs e)
    {
        var d = sender as DependencyObject;
        if (d == null)
            return;
        var command = GetCommand(d);
        if (command == null)
            return;
        var parameter = GetCommandParameter(d);
        if (!command.CanExecute(parameter))
            return;
        command.Execute(parameter);
    }
}

With that in your toolbox, you can write XAML like this (assuming PersonViewModel contains the string properties Name and Title, and an ICommand property named SayHiCommand that expects a string parameter):

<ListView ItemsSource="{Binding Persons}" >
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="local:HandleDoubleClickBehavior.Command" Value="{Binding SayHiCommand}" />
            <Setter Property="local:HandleDoubleClickBehavior.CommandParameter" Value="{Binding Name}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}" />
        </GridView>
    </ListView.View>
</ListView>
Mucky answered 1/3, 2016 at 23:33 Comment(0)
M
2

For those here that are using a framework like Prism where the main usercontrol containing the Listview is a View (not a window) that is bound to a viewmodel.

The answer of dlf is the best with these small tweaks:

{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, 
         Path=DataContext.SayHiCommand}

And in the special behavior attached property you change the ICommand cast to a DelegateCommand cast.

Works like a charm, Thank you very much.

Monarchal answered 27/11, 2020 at 17:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.