关于wpf:带有MVVM Light的CommandParameter

CommandParameter with MVVM Light

我正在尝试使RelayCommand与使用MVVM Light的CommandParameter一起使用。 该命令在我的视图模型中定义,我想将所选的ListBox项作为参数传递。 该命令已绑定,但参数未绑定。 这可能吗?

1
2
3
4
5
6
7
8
9
10
<UserControl x:Class="Nuggets.Metro.Views.EmployeeListView"
         ...
         DataContext="{Binding EmployeeList,Source={StaticResource Locator}}">
   <ListBox x:Name="lstEmployee" ItemsSource="{Binding EmployeeItems}" Style="{StaticResource EmployeeList}" Tag="{Binding EmployeeItems}">
        <ListBox.ContextMenu>
            <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                <MenuItem Header="Edit item" Command="{Binding EditEmployeeCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem,RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"/>
                <MenuItem Header="Delete item" Command="{Binding DeleteEmployeeCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem,RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"/>
            </ContextMenu>
        </ListBox.ContextMenu>

这适用于带有MVVM的TreeView或ListView。
ContextMenu中的PlacementTarget是(这里)Listview

1
2
3
4
5
6
7
8
<ListView.ContextMenu>
  <ContextMenu>
     <MenuItem x:Name="OpenExplorer"Header="ShowFolder"                  
      Command="{Binding ShowExplorer}"
      CommandParameter ="{Binding Path=PlacementTarget.SelectedItem,
            RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
   </ContextMenu>
</ListView.ContextMenu>


这应该有效

1
2
3
4
5
6
7
8
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
  <MenuItem Header="Edit item"
            Command="{Binding EditEmployeeCommand}"
            CommandParameter="{Binding SelectedItem,ElementName=lstEmployee}"/>
  <MenuItem Header="Delete item"
            Command="{Binding DeleteEmployeeCommand}"
            CommandParameter="{Binding SelectedItem,ElementName=lstEmployee}"/>
 </ContextMenu>

在CommandParameter的绑定中使用ListBox和ElementName的名称,并将路径设置为SelectedItem。

更新:

上面的代码不适用于ListBox和ContextMenu,因为它们属于不同的可视树。 结果是

1
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=lstEmployee'. BindingExpression:Path=SelectedItem; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'CommandParameter' (type 'Object')

以下XAML可以完成这项工作。 使用ContextMenu的PlacementTarget(即ListBox)。

1
2
3
4
5
6
7
8
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
  <MenuItem Header="Edit item"
            Command="{Binding EditEmployeeCommand}"
            CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"/>
  <MenuItem Header="Delete item"
            Command="{Binding DeleteEmployeeCommand}"
            CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"/>
</ContextMenu>