WPF ContextMenu忽略CanExecute

时间:2017-10-17 13:50:31

标签: c# wpf xaml

我有一个带有元素的DataGrid和这个视图后面的ViewModel。 ViewModel有一个RelayCommand,它实现了CanExecuteChanged。 DataGridRow的Style具有ContextMenu,其MenuItems绑定到RelayCommand并将该项作为参数传递。 这是XAML:

<ContextMenu  x:Key="CommentMenu" DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}">       
    <MenuItem Header="Bind to Project" Command="{Binding BindToProjectCommand}" 
              CommandParameter="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}"/>        

</ContextMenu>
<Style x:Key="DefaultRowStyle" TargetType="{x:Type DataGridRow}">
    <Setter Property="ContextMenu" Value="{StaticResource CommentMenu}" />
</Style>
...
<DataGrid ItemsSource="{Binding Comments}"
                  RowStyle="{StaticResource DefaultRowStyle}"
                  IsReadOnly="True"
                  CanUserAddRows="False">

这是ViewModel:

public MyViewModel()
{
   BindToProjectCommand = new RelayCommand<Comment>(BindToProject, CanBindToProject);
}

public bool CanBindToProject(Comment comment)
{
    var answer = comment != null && comment.ProjectId == null;
    return answer;
}

在运行时调用CanExecuteChanged,正确的注释作为参数传递,返回true,但仍然禁用菜单项。 “输出”窗口没有绑定错误,因此绑定肯定是正确的,我可以看到正确的实例。 所以问题是: 1.为什么CanExecute的结果被忽略了? 2.如何使其发挥作用?

感谢您的投入。

1 个答案:

答案 0 :(得分:0)

所以我发现CommandParameter的绑定总是绑定到列表中的最后一个注释。最简单的解决方法是将SelectedItem绑定到ViewModel中的属性,并按如下方式更改命令和CanBindToProject方法:

            <DataGrid ItemsSource="{Binding Comments}"              
                  IsReadOnly="True"
                  CanUserAddRows="False"
                  RowStyle="{StaticResource DefaultRowStyle}"
                  SelectedItem="{Binding SelectedComment}"
                  SelectionMode="Single"/>

public Comment SelectedComment
public RelayCommand BindToProjectCommand(BindToProject, CanBindToProject)

public bool CanBindToProject()
{
     return SelectedComment != null && SelectedComment.ProjectId == null;
}