Denis
Denis

Reputation: 344

Track where I clicked in ListView MVVM

I am writing a folder browser and I want to open folders on double click. My folders are binded to ListView with GridView inside and I am tracking double click like this:

<i:EventTrigger EventName="MouseDoubleClick">
                    <Custom:EventToCommand Command="{Binding FolderOpenedCommand, Mode=OneWay}" CommandParameter="{Binding SelectedItem, ElementName=FolderView}"/>
                </i:EventTrigger>

But I have an annoying issue: if I double click on gridview splitter to autosize column, it will also open selected folder, which I am not want to. So, I have several options for now: put event handler inside style and use it with code behind or leave it as is, but in my case I want to do implement it with MVVM scenario because codebehind is not suitable for me.

My question is: how I can send my parameter as SelectedItem only if I click on the item and null when I click on something else?

I want to track this to make a proper behavior as far as I cannot apply double click to gridview on some reason.

Could someone please help me with this problem?

EDIT: Lets clarify one thing to be sure we speak about the same things: I can define something like this

<Style x:Key="itemStyle" TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource MetroListViewItem}">
     <EventSetter Event="MouseDoubleClick" Handler="FolderView_OnMouseDoubleClick"></EventSetter>
  </Style>

Bu I cannot do like this:

<Style x:Key="itemStyle" TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource MetroListViewItem}">
     <EventSetter Event="MouseDoubleClick" Handler="{Binding OpenFilesCommand}"></EventSetter>
  </Style>

Because It will lead to exception. Now I want to understand how I can apply command here if Handler does not accept command? Do I need to write some attached property?

Upvotes: 0

Views: 200

Answers (3)

Liero
Liero

Reputation: 27350

Avoid using listview. Use DataGrid instead. Then you can add eventtrigger to row style. ListView is obsolete class introduced in wpf 3 that was replaced by datagrid in wpf 4 an there no reason to use it anymore.

Another option is to use use custom behaviour implemented as attached property, e.g. InvokeCommandOnRowDoubleClick attached to Grid. To learn more about attached behaviours read this: http://blogs.msdn.com/b/dgartner/archive/2009/11/11/wpf-attached-behavior-example-watermark-text.aspx

Upvotes: 1

Denis
Denis

Reputation: 344

Well, to solve this issue I had to use InputBindings property for each control in each gridview column. I put Grid over controls and made like this:

<GridViewColumn Header="Size (Bytes)">
              <GridViewColumn.CellTemplate>
                 <DataTemplate>
                    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                       <Grid.InputBindings>
                          <MouseBinding Gesture="LeftDoubleClick" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.FolderOpenedCommand}" 
                                   CommandParameter="{Binding ElementName=FolderView, Path=SelectedItem}"></MouseBinding>
                       </Grid.InputBindings>
                       <TextBlock Text="{Binding Path=Size, StringFormat='{}{0:#,#.}'}"/>
                    </Grid>
                 </DataTemplate>
              </GridViewColumn.CellTemplate>
           </GridViewColumn>

Unfortunately for my case I didnt find better solution

Upvotes: 0

Thomas Bouman
Thomas Bouman

Reputation: 608

There is a MouseDoubleClick property on the ListViewItem control. You can rework your style to contain a correct event when double clicking an item, apply it only to the ListViewItems and it won't listen to that event when not double clicking the gridview splitter.

You can read more about this here.

Upvotes: 0

Related Questions