Pregunta

I have a ListView/GridView setup and I want to handle a right click on the dislayed items. Is there are Databinding-way of doing this? I have seen complicated workarounds like handling the super-elements event and poking around to find its origin, but that feels awfully bloated for such basic request.

What I'd love to see is something like binding the event to an action of the item's ViewModel - is there a way to do that? Similar to this, but I can't quite wrap my head around how to adapt that to work on a single ListView item (I am not even sure that's possible, tbh).

Rough outline:

<ListView>
    <ListView.View>
        <GridView />
    </ListView.View>
    <ListView.Resources>
        <Style TargetType="{x:Type ListViewItem}">
        </Style>
    </ListView.Resources>
</ListView/>
¿Fue útil?

Solución

There is a way using the Interactivity assembly form the Blend SDK. It will provide an EventTrigger which executes a command when an event is raised.

<!--
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
-->

<Button Content="Click me">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:InvokeCommandAction Command="{Binding ClickCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

Edit:

A possible solution for your problem could look like this:

View:

<ListView x:Name="listView">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseRightButtonUp">
            <i:InvokeCommandAction Command="{Binding RightClickOnItemCommand}"
                                   CommandParameter={Binding SelectedItem, ElementName=listView} />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListView>

ViewModel:

public ICommand RightClickOnItemCommand { get; set; }

public void RightClickOnItem(object item)
{
}

Otros consejos

You could try to create a style template for the list view item, and add an attached behaviour to it to handle mouse clicks.

public static readonly DependencyProperty PreviewMouseLeftButtonDownCommandProperty =
        DependencyProperty.RegisterAttached("PreviewMouseLeftButtonDownCommand", typeof (ICommand),
            typeof (MouseBehaviour), new FrameworkPropertyMetadata(PreviewMouseLeftButtonDownCommandChanged));

    private static void PreviewMouseLeftButtonDownCommandChanged(DependencyObject dependencyObject,
        DependencyPropertyChangedEventArgs args)
    {
        var element = (FrameworkElement) dependencyObject;
        element.PreviewMouseLeftButtonDown += Element_PreviewMouseLeftButtonDown;
    }

    private static void Element_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs args)
    {
        var element = (FrameworkElement) sender;
        ICommand command = GetPreviewMouseLeftButtonDownCommand(element);
        if (command != null)
        {
            command.Execute(args);
        }
    }

    public static void SetPreviewMouseLeftButtonDownCommand(UIElement element, ICommand value)
    {
        element.SetValue(PreviewMouseLeftButtonDownCommandProperty, value);
    }

    public static ICommand GetPreviewMouseLeftButtonDownCommand(UIElement element)
    {
        return (ICommand) element.GetValue(PreviewMouseLeftButtonDownCommandProperty);
    } 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top