Search code examples
c#wpfmvvmmvvm-lightrelaycommand

RelayCommand canexecute never gets re-evaluated


I have an application, which uses RelayCommands in an MVVM architecture.

It seems that at some point in time the CanExecute methods no longer get properly re-evaluated. (maybe installing latest updates for VS2013 caused this?).

The code below seems as basic as it can get, I really hope somebody can help me out.

Declaration of relay command:

public RelayCommand BrowseTorrentSiteCommand { get; private set; }

Instantiation of relay command:

BrowseTorrentSiteCommand = new RelayCommand(BrowseTorrentSiteOnExecuted, BrowseTorrentSiteOnCanExecute); 

Implementation of CanExecute:

private bool BrowseTorrentSiteOnCanExecute()
{
    return _mainViewViewModel.SelectedTvShow != null;
}

Implementation of SelectedTvShow property in VM:

public TvShowViewModel SelectedTvShow
{
    get { return _selectedTvShow; }
    set
    {
        _selectedTvShow = value; 
        OnPropertyChanged();
    }
}

Updating the selected tv show:

    public void TvShowsSelectionChanged()
    {
        Episodes.Clear();

        var queryEpsidesForSelection = new QueryEpsidesForSelection(TvShows);
        foreach (var episode in queryEpsidesForSelection.QueryEpisodes())
        {
            Episodes.Add(episode);
        }
        SelectedTvShow = queryEpsidesForSelection.SelectedTvShow;
        MainCommandsViewModel.DownloadNewestEpisodesCommand.RaiseCanExecuteChanged();
        //MainCommandsViewModel.BrowseTorrentSiteCommand.RaiseCanExecuteChanged();
    }

I intentionally commented the last line where I force the RaiseCanExecuteChanged being called, I NEVER had to use that before. Obviously this solves the problem, but I use a lot of RelayCommands and all of them seem to suffer from the same problem: their CanExecute methods are no longer re-evaluated automatically.

What can be the cause that the CanExecute method no longer gets fired ?


Solution

  • Update

    There are two implementations of the RelayCommand in MvvmLight.

    • One in using GalaSoft.MvvmLight.Command;
    • One in using GalaSoft.MvvmLight.CommandWpf;

    I changed the namespace to using GalaSoft.MvvmLight.CommandWpf; and everything works as before...

    In the comment of this implementation of RelayCommand the following comment gave it away:

    // Remarks:
    //     If you are using this class in WPF4.5 or above, you need to use the GalaSoft.MvvmLight.CommandWpf
    //     namespace (instead of GalaSoft.MvvmLight.Command).  This will enable (or
    //     restore) the CommandManager class which handles automatic enabling/disabling
    //     of controls based on the CanExecute delegate.
    

    Anyway, problem solved... (took me long enough...)

    Orginal answer

    @KingKong,

    Maybe I interpret your comment wrong, but this works fine in a sample App I just created to check my sanity.

        public MainViewModel()
        {
            Command1 = new RelayCommand(OnCommand1Executed, () => true);
            Command2 = new RelayCommand(OnCommand2Executed, OnCommand2CanExecute);
        }
    
        private void OnCommand1Executed()
        {
            _command2CanExecute = true;
        }
    
        private void OnCommand2Executed()
        {
            // Not implemented
        }
    
        private bool OnCommand2CanExecute()
        {
            return _command2CanExecute;
        }
    

    The UI on top of this will enable button2 when button1 is executed.

    Still, this basic behavior seems not to be working in my other application...

    Any help would be greatly appreciated.