从xaml传递命令参数

时间:2011-11-16 15:32:13

标签: wpf xaml binding mvvm icommand

我尝试做这样的事情:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}">
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding RemoveRow}" 
              CommandParameter="{Binding ElementName=myGrid, Path=SelectedItem}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>

但我总是得到null(我也试过SelectedIndex和SelectedValue)

如果我将以下参数传递给执行代码,它可以工作:

<MenuItem Command="{Binding RemoveRow}" CommandParameter="1">

2 个答案:

答案 0 :(得分:21)

在CommandParameter中尝试这样的事情,

<DataGrid.ContextMenu>
     <ContextMenu>
           <MenuItem Header="MyHeader" 
                     Command="{Binding MyCommand}"
                     CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItem}" />
</DataGrid.ContextMenu>

我已经测试了它,它应该可以工作。

答案 1 :(得分:18)

它不起作用,因为ContextMenu不是DataGrid的可视或逻辑树的一部分,因此它不会继承DataContext

据我所知,仅使用内置绑定系统就可以轻松解决此问题。但是,使用解释为here的简单“代理”类,您可以解决此问题:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}">
   <DataGrid.Resources>
       <local:BindingProxy x:Key="proxy" Data="{Binding}" />
   </DataGrid.Resources>
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding Data.RemoveRow, Source={StaticResource proxy}}" 
              CommandParameter="{Binding ElementName=myGrid, Path=SelectedItem}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>

但是您仍然遇到问题:ElementName=myGrid无效(再次,因为ContextMenu不在DataGrid的可视或逻辑树中,所以它不在同名范围)。一个简单的解决方案是将SelectedItem的{​​{1}}绑定到ViewModel的属性,并使用该属性而不是命令参数:

DataGrid