wpf 从 xaml 传递命令参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8154202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:10:41  来源:igfitidea点击:

Pass command parameter from the xaml

wpfxamlbindingmvvmicommand

提问by Maya

I try to do something like this:

我尝试做这样的事情:

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

but I got null always (I tried also SelectedIndex and SelectedValue)

但我总是为空(我也试过 SelectedIndex 和 SelectedValue)

if I pass the following parameter to the execution code, it works:

如果我将以下参数传递给执行代码,它会起作用:

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

回答by Rayan Elmakki

Try something like this in your CommandParameter,

在您的 CommandParameter 中尝试类似的操作,

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

I already tested it and it should work.

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

回答by Thomas Levesque

It doesn't work because the ContextMenuis not part of the visual or logical tree of the DataGrid, so it doesn't inherit the DataContext.

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

As far as I know, there is know easy solution to this problem using only the built-in binding system. However, using a simple "proxy" class as explained here, you can work around this problem:

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

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

However you still have a problem: ElementName=myGriddoesn't work (again, because ContextMenuisn't in the visual or logical tree of the DataGrid, so it's not in the same name scope). A simple solution is to bind the SelectedItemof the DataGridto a property of the ViewModel, and use that property instead of the command parameter:

但是你仍然有一个问题:ElementName=myGrid不起作用(同样,因为ContextMenu不在 的可视化或逻辑树中DataGrid,所以它不在同一个名称范围内)。一个简单的解决方案是结合SelectedItemDataGrid所述视图模型的属性,并使用该属性,而不是命令参数:

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