Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RelayCommand CanExecute behavior not working

Tags:

c#

wpf

mvvm-light

I'm having trouble getting the RelayCommand to enable/disable the attached control properly.

I've got an EventToCommand element attached to a button. The command is databound to the ViewModel. Initially, the button is disabled (expected behavior), but I cannot seem to get the CanExecute logic to check it's value. When CurrentConfigFile is set and exists, the button should be enabled. I've executed code and checked the file's value in debug to make sure it's set, but the control is still disabled. I've tried CommandManager.InvalidateRequerySuggested() and command.RaiseCanExecuteChanged(), but it will not enable.

I've wondered if lambdas don't work correctly for the CanExecute behavior (even though the examples use them) or that the CanExecute behavior needs to be databound to another element.

Here's my code:

// The FileInfo being checked for existence before the button should be enabled
public const string CurrentConfigFilePN = "CurrentConfigFile";
public FileInfo CurrentConfigFile
{
    get
    {
        return _currentConfigFile;
    }

    set
    {
        if (_currentConfigFile == value)
        {
            return;
        }

        var oldValue = _currentConfigFile;
        _currentConfigFile = value;

        // Update bindings, no broadcast
        RaisePropertyChanged(CurrentConfigFilePN);
    }
}

public MainViewModel()
{
    // snip //

    SaveCommand = new RelayCommand(SaveConfiguration, 
        () => CurrentConfigFile != null && CurrentConfigFile.Exists);
    }

private void SaveConfiguration()
{

    // export model information to xml document
    ExportXMLConfiguration(CurrentConfigFile);

}

and markup

<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <GalaSoft:EventToCommand x:Name="SaveETC" 
                Command="{Binding SaveCommand}" 
                MustToggleIsEnabledValue="true" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

Update:

As per Isak Savo's suggestion, I bound the RelayCommand directly to the button with

<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5" 
Command="{Binding SaveCommand}"/>

and it started disabled and correctly enabled when the FileInfo was set. Guess I should remember not to fix what isn't broken!

like image 892
llaughlin Avatar asked Jul 02 '26 04:07

llaughlin


1 Answers

Why don't you just bind to the Command directly from the Button?

<Button Command="{Binding SaveCommand}" Content="Save" />

Maybe the EventToCommand thing you are using is messing things up with the command's CanExecute notification.

And regarding the CanExecute problem - are you sure that your CanExecute handler is called after the CurrentConfigFile property is set? I've found that even though WPF mostly does a good job of requerying CanExecute, I still sometimes need to force a requery through the CommandManager.

EDIT: As pointed out in the comments, the OP has already tried the command manager approach.

like image 151
Isak Savo Avatar answered Jul 03 '26 17:07

Isak Savo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!