【问题标题】:Binding a RelayCommand AND an additional condition绑定 RelayCommand 和附加条件
【发布时间】:2012-03-09 20:45:33
【问题描述】:

我正在尝试将主窗口中的 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)的listview中至少选择了两个项目。)

有人可以帮忙吗?

【问题讨论】:

    标签: c# wpf binding converter relaycommand


    【解决方案1】:

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


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

    要解决这个问题,您可以将FallbackBalue=false 添加到您的绑定中,这会告诉绑定在找不到源时使用false。并且还添加TargetNullValue=false 这告诉绑定在源为空时使用false(在这种情况下为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.
    }
    

    【讨论】:

    • 我只想调用一个命令,但该命令位于子视图模型内部,并不总是打开。所以我只能在 CurrentChildViewModel 不为空时调用它。
    • 这对我来说没有意义,你需要澄清你不明白的地方。
    • 我在我真正想要的问题中添加了一行:我希望仅当 CurrentChildViewModel != null 并且 CurrentChildViewModel.CanExecuteCompactCommand() 返回 true 时才启用菜单项。您说 CanExecuteCompactCommand 应该被删除,但它包含一些能够执行命令所必需的先决条件。我将在问题中添加更多文本。
    • tgetNullValue 应该设置为 false,我已经更正了答案中的错误。
    • 我猜你已经使用了我在我的建议中发布的关于你应该如何做你想做的事情的风格。这种风格适用于所有MenuItems,即使是那些本应没有命令并因此被禁用的人。我已经为Style 添加了一个名称,并将其应用于答案中的MenuItem
    猜你喜欢
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 2015-06-07
    • 2014-09-29
    相关资源
    最近更新 更多