WPF MVVM模式下如何实现ListViewItem左键双击触发ViewModel方法
解决方法
方案1:通过传递事件参数判断鼠标按键
第一步 修改XAML配置
将InvokeCommandAction设置为传递事件触发时的原生参数,你已经绑定了SelectedItem到SelectedStructObject属性,不需要额外传递选中项:
<i:Interaction.Triggers> <i:EventTrigger EventName="MouseDoubleClick"> <i:InvokeCommandAction Command="{Binding Command}" PassEventArgsToCommand="True"/> </i:EventTrigger> </i:Interaction.Triggers>
第二步 调整ViewModel命令逻辑
在RelayCommand的执行方法里转换参数,判断鼠标按键:
public MainViewModel() { Command = new RelayCommand(o => { // 将参数转换为鼠标事件参数 if (o is MouseButtonEventArgs mouseArgs && mouseArgs.ChangedButton == MouseButton.Left) { // 绑定的SelectedStructObject已经同步为当前选中的项,非空判断避免双击空白区域的误触发 if (SelectedStructObject != null) { // 此处写你需要执行的业务逻辑 } } }); StructObjects = new ObservableCollection<StructElement>(); }
方案2:优化触发范围,仅双击ListViewItem时生效
方案1双击ListView空白区域也会触发命令,如果你需要严格限制只有双击列表项才触发,可以把触发器写到Item容器的样式里:
<ListView ...> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="i:Interaction.Triggers"> <Setter.Value> <i:TriggerCollection> <i:EventTrigger EventName="MouseDoubleClick"> <i:InvokeCommandAction Command="{Binding DataContext.Command, RelativeSource={RelativeSource AncestorType=ListView}}" PassEventArgsToCommand="True" CommandParameter="{Binding}"/> </i:EventTrigger> </i:TriggerCollection> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle> ... </ListView>
这种写法下Command会直接拿到当前双击的StructElement对象,不需要依赖全局的选中属性:
Command = new RelayCommand(o => { if (o is MouseButtonEventArgs mouseArgs && mouseArgs.ChangedButton == MouseButton.Left) { // 从事件源获取当前双击的列表项对应的数据对象 var clickedItem = (mouseArgs.OriginalSource as FrameworkElement)?.DataContext as StructElement; if (clickedItem != null) { // 执行业务逻辑 } } });
推荐学习知识点
- WPF MVVM模式核心概念:数据绑定、命令绑定、
INotifyPropertyChanged通知变更接口 System.Windows.Interactivity交互触发器的常用用法- WPF路由事件的传递机制
ICommand接口的实现原理,RelayCommand的作用和扩展方式
内容的提问来源于stack exchange,提问作者ominaei
相关产品推荐
相关产品推荐

