0

我正在尝试将主窗口中的 RelayCommand 的 CanExecute 绑定到可能不存在的子窗口。我该怎么做?

目前我有:

<MenuItem Header="_Compact" 
       Command="{Binding Path=CurrentChildViewModel.CompactCommand}"
       IsEnabled="{Binding CurrentChildViewModel.CanExecuteCompactCommand, 
        Converter={StaticResource NullToBooleanConverter}}"/>

然而,这似乎不起作用,因为转换器应该在 CurrentChildViewModel 上工作(而不是 CanExecuteCompactCommand,但我也应该以某种方式包含那个 CanExecuteCompactCommand。

我希望仅当 CurrentChildViewModel != null 并且 CurrentChildViewModel.CanExecuteCompactCommand() 返回 true 时才启用菜单项。

(原因:CurrentChildViewModel是一个窗口的ViewModel,可以打开也可以不打开,如果没有打开,我希望菜单项被禁用。如果它打开,我希望Compact命令的CanExecute方法检查compact命令是否可以执行,这就像在 ChildView (Model) 中的列表视图中至少选择了两个项目。)

有人可以帮忙吗?

4

1 回答 1

1

如果您的转换器需要然后绑定到该实例CurrentChildViewModel而不是命令(删除.CanExecuteCompactCommand)那说明为什么您到底使用一个命令来确定另一个命令是否应该能够执行?您应该使用命令的 CanExecute ( CompactCommand)。


好的,我想我现在了解您的实际问题。如果我是正确的,那么您的 xaml/bindings 将按预期工作,除非其中一个CurrentChildViewModelCanExecuteCompactCommand为空。(假设您删除了转换器。)

要解决这个问题,您可以添加FallbackBalue=false到绑定中,这会告诉绑定在false找不到源时使用。并且还添加TargetNullValue=falsethis 告诉绑定false在源为 null 时使用(CompactCommand在这种情况下)

所以它看起来像:

IsEnabled="{Binding CurrentChildViewModel.CanExecuteCompactCommand,
                    FallbackValue=false,
                    TargetNullValue=false}"

也就是说,我仍然不鼓励使用命令来确定另一个命令是否可以执行。我会做这样的事情:

例如

<Style TargetType="{x:Type MenuItem}" x:Key="menuItemWithCommand">
    <Style.Triggers>
        <Trigger Property="Command" value="{x:Null}">
            <Setter Property="IsEnabled" Value="False"/>
        </Trigger>
    </Style.Triggers>
</Style>
...
<MenuItem Header="_Compact"
          Style="{StaticResource menuItemWithCommand}"
          Command="{Binding Path=CurrentChildViewModel.CompactCommand}" />
...
CompactCommand= new RelayCommand(CompactCommandExecuted, CompactCommandCanExecute);
private void CompactCommandExecuted(obejct obj)
{   // Do your business
}
private bool CompactCommandCanExecute(object obj)
{
    // return true if the command is allowed to be executed; otherwise, false.
}
于 2012-02-19T00:23:13.360 回答