绑定RelayCommand和附加条件

时间:2012-02-19 00:08:32

标签: c# wpf binding converter relaycommand

我正在尝试将主窗口中的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)列表视图中的至少两个项目。)

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

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


好的,我想我现在明白你的实际问题。 如果我是正确的,那么除非CurrentChildViewModelCanExecuteCompactCommand为空,否则您的xaml /绑定将按预期工作。 (假设您删除了转换器。)

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

所以它看起来像:

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

那说我仍然会阻止使用命令来确定是否可以执行另一个命令。我会做这样的事情:

e.g。

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