跟踪我在 ListView MVVM 中单击的位置

Track where I clicked in ListView MVVM

我正在编写一个文件夹浏览器,我想双击打开文件夹。 我的文件夹绑定到内部带有 GridView 的 ListView,我正在跟踪双击,如下所示:

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

但我有一个烦人的问题:如果我双击 gridview 拆分器以自动调整列大小,它也会打开选定的文件夹,这是我不想的。 所以,我现在有几个选择:将事件处理程序放在样式中并在代码后面使用它或保持原样,但在我的情况下我想用 MVVM 场景实现它,因为代码隐藏不适合我。

我的问题是:如何才能仅在单击该项目时将我的参数作为 SelectedItem 发送,而在我单击其他项目时发送 null?

由于某些原因我无法对 gridview 应用双击,我想跟踪它以做出正确的行为。

有人可以帮我解决这个问题吗?

编辑: 让我们澄清一件事,以确保我们谈论的是同一件事: 我可以这样定义

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

但是我不能这样做:

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

因为会导致异常。现在我想了解如果 Handler 不接受命令,我如何在此处应用命令?我需要写一些附件吗属性?

ListViewItem控件上有一个MouseDoubleClick属性。您可以修改样式以在双击项目时包含正确的事件,仅将其应用于 ListViewItems 并且在不双击 gridview 拆分器时它不会侦听该事件。

您可以阅读更多相关内容 here

嗯,为了解决这个问题,我不得不为每个 gridview 列中的每个控件使用 InputBindings 属性。我将 Grid 放在控件上并像这样制作:

<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>

不幸的是,我没有找到更好的解决方案

避免使用列表视图。请改用 DataGrid。然后您可以将事件触发器添加到行样式。 ListView 已过时 class 在 wpf 3 中引入,在 wpf 4 中被 datagrid 取代,没有理由再使用它了。

另一种选择是使用作为附件 属性 实现的自定义行为,例如InvokeCommandOnRowDoubleClick 附加到网格。要了解有关附加行为的更多信息,请阅读:http://blogs.msdn.com/b/dgartner/archive/2009/11/11/wpf-attached-behavior-example-watermark-text.aspx