我知道这是一篇旧帖子,但有人可能会觉得这很有用。假设您已将视图绑定到您的视图模型,那么您可以通过以下方式将您的 ContextMenu.DataContext 绑定到您的视图模型:
首先,将您的视图命名为UserControl...为简单起见,我通常将我的所有视图命名为This。然后记住我们的视图模型是绑定到UserControl的DataContext,我们可以使用{Binding DataContext, ElementName=This}绑定到视图模型。
所以现在我们可以绑定到视图模型,我们必须将它与ContextMenu.DataContext 连接起来。我使用对象的Tag 属性和ContextMenu(PlacementTarget)作为连接,在本例中为Grid:
<DataTemplate x:Key="YourTemplate" DataType="{x:Type DataTypes:YourDataType}">
<Grid ContextMenu="{StaticResource Menu}" Tag="{Binding DataContext,
ElementName=This}">
...
</Grid>
</DataTemplate>
然后我们可以通过将ContextMenu.DataContext 属性绑定到PlacementTarget.Tag 属性(在我们的示例中为Grid)来访问ContextMenu 中的视图模型属性和命令:
<ContextMenu x:Key="Menu" DataContext="{Binding PlacementTarget.Tag, RelativeSource=
{RelativeSource Self}}">
<MenuItem Header="Delete" Command="{Binding DeleteFile}" CommandParameter=
"{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource
AncestorType=ContextMenu}}" CommandTarget="{Binding PlacementTarget,
RelativeSource={RelativeSource Self}}" />
</ContextMenu>
注意MenuItem.CommandTarget 属性上的绑定。设置此项可确保引发指定命令的目标元素是PlacementTarget,或在本例中为Grid。
还要注意CommandParameter 绑定。这将绑定到PlacementTarget 的DataContext,或者在这种情况下绑定到Grid。 Grid 的 DataContext 将从 DataTemplate 继承,因此如果您正在使用 ICommand 接口的某些实现,则您的数据项现在绑定到 Command 中的 object 参数:
public bool CanExecuteDeleteFileCommand(object parameter)
{
return ((YourDataType)parameter).IsInvalid;
}
public void ExecuteDeleteFileCommand(object parameter)
{
Delete((YourDataType)parameter);
}
或者,如果您在视图模型中直接使用某种RelayCommand 委托:
public ICommand Remove
{
get
{
return new ActionCommand(execute => Delete((YourDataType)execute),
canExecute => return ((YourDataType)canExecute).IsInvalid);
}
}