Question

I am trying to bind a RelayCommand's CanExecute in my main window to a child window that possibly does not exist. How should I do it?

Currently I have:

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

However this does not seem to work because the converter should work on CurrentChildViewModel (and not the CanExecuteCompactCommand, but I also should include that CanExecuteCompactCommand somehow.

I want the menu item to be enabled only if CurrentChildViewModel != null and CurrentChildViewModel.CanExecuteCompactCommand() returns true.

(reason: the CurrentChildViewModel is a window's ViewModel that can be opened or not, if it is not opened, I want the menu item to be disabled. And if it is opened, I want the Compact command's CanExecute method to check if the compact command can be executed, which is something like at least two items in the listview in the ChildView (Model) are selected.)

Can anybody help please?

Était-ce utile?

La solution

if your converter need the instance of CurrentChildViewModel then bind to that and not the command (remove .CanExecuteCompactCommand) That said why on earth are you using one command to determine if another command should be able to execute? You should utilize the CanExecute of your command (CompactCommand).


Ok I think I understand your actual problem now. If I'm correct then your xaml/bindings work as expected unless either CurrentChildViewModel or CanExecuteCompactCommand is null. (assuming you remove your converter.)

To solve this you can add FallbackBalue=false to your binding, this tells the binding to use false when it cannot find the source. And also add TargetNullValue=false this tells the binding to use false when the source is null (CompactCommand in this case)

So it would look like:

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

That said I still would discourage the usage of a command to determine if another command can execute. I would do would do something like this:

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.
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top