3

Do anyone know why being specific with the MVVM Light RelayCommand generic type would cause its canExecute to always resolve to false for the binding? In order to get the correct behavior I had to use an object and then convert it to the desired type.

NOTE: canExecute was simplified to a boolean for testing the block that does not work and is normally a property CanRequestEdit.

Does NOT work:

public ICommand RequestEditCommand {
  get {
    return new RelayCommand<bool>(commandParameter => { RaiseEventEditRequested(this, commandParameter); },
                                  commandParameter => { return true; });
  }
}

Works:

public ICommand RequestEditCommand {
  get {
    return new RelayCommand<object>(commandParameter => { RaiseEventEditRequested(this, Convert.ToBoolean(commandParameter)); },
                                    commandParameter => { return CanRequestEdit; });
  }
}

XAML:

<MenuItem Header="_Edit..." Command="{Binding RequestEditCommand}" CommandParameter="true"/>
Rock
  • 182
  • 11
  • 1
    I think that CommandParameter is going as a string. – sexta13 Mar 21 '16 at 15:11
  • You are correct, CommandParameter is going as a string. How do you think that this would have an affect on canExecute which is hard coded to return true? – Rock Mar 21 '16 at 15:18
  • strange...can you try to put in a function? something like: RelayCommand x = new RelayCommand(req => { string s = "true"; }, req => canExecute()); private bool canExecute() { return true } – sexta13 Mar 21 '16 at 15:25
  • The suggested change yielded the same result. As a side note, how is it that you thought this might be different than the in line lambda? I know that sometimes expected behavior yields different results, so I am just curious what your thought process was. – Rock Mar 21 '16 at 17:11

1 Answers1

2

Look at the code for RelayCommand<T>, specifically the line I marked with "!!!":

public bool CanExecute(object parameter)
{
    if (_canExecute == null)
    {
        return true;
    }

    if (_canExecute.IsStatic || _canExecute.IsAlive)
    {
        if (parameter == null
#if NETFX_CORE
            && typeof(T).GetTypeInfo().IsValueType)
#else
            && typeof(T).IsValueType)
#endif
        {
            return _canExecute.Execute(default(T));
        }

        // !!!
        if (parameter == null || parameter is T)
        {
            return (_canExecute.Execute((T)parameter));
        }
    }

    return false;
}

The parameter you are passing to your command is the string "true", not the boolean true, so the condition will fail because parameter is not null and the is clause is false. In other words, if the value of the parameter doesn't match the type T of the command, then it returns false.

If you really want to hard-code a boolean into your XAML (i.e. your sample isn't dummy code), then look to this question for ways to do so.

Community
  • 1
  • 1
Patrick Quirk
  • 23,334
  • 2
  • 57
  • 88
  • Thank you for clearing that up! After a closer look I believe that is what sexta13 was eluding to but the verbose answer you provided is more correct. – Rock Mar 21 '16 at 17:49