6

I am using the MVVM Light library. From this library I use RelayCommand<T> to define commands with an argument of type T.

Now I have defined a RelayCommand that requires an argument of type Nullable<bool>:

    private RelayCommand<bool?> _cmdSomeCommand;
    public RelayCommand<bool?> CmdSomeCommand
    {
        get
        {
            if (_cmdSomeCommand == null)
            { _cmdSomeCommand = new RelayCommand<bool?>(new Action<bool?>((val) => { /* do work */ })); }
            return _cmdSomeCommand;
        }
    }

How can I assign the CommandParameter from my XAML code?

I've tried to pass a boolean value, but that causes the following exception:

System.InvalidCastException: Invalid cast from 'System.Boolean' to 'System.Nullable`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.

I've also tried to define static properties containing the bool? values and reference them from XAML:

public static class BooleanHelper
{
    public static bool True { get { return true; } }
    public static bool False { get { return false; } }

    public static bool? NullableTrue { get { return true; } }
    public static bool? NullableFalse { get { return false; } }
}

XAML:

<Button Command="{Binding CmdSomeCommand}" CommandParameter="{x:Static my:BooleanHelper.NullableTrue}" />

But this causes the same exception to be thrown. I've also tried to return new Nullable<bool>(true), but as expected, this has the same result.

Chris
  • 323
  • 2
  • 12
  • Have you seen this? http://stackoverflow.com/questions/2850629/declare-a-nullable-int-int-using-xaml – tolanj Dec 22 '16 at 11:56
  • While not really a solution to the problem, one can define the parameter as `object` and cast 'manually' in the action body. – wondra Jul 17 '20 at 08:10

1 Answers1

2

Looks like MVVM Light is at fault for handling the parameter differently between Execute and CanExecute and not handling nullable in a proper way.

See the code at https://github.com/paulcbetts/mvvmlight/blob/master/GalaSoft.MvvmLight/GalaSoft.MvvmLight%20(NET35)/Command/RelayCommandGeneric.cs#L198 Lines 198-205

What happens there leads to your exception and can be easily reproduced with the following code:

object t1 = (bool?)true;
// issue: for Nullable<T>, GetType will return T
if (t1.GetType() != typeof(bool?))
{
    if (t1 is IConvertible)
    {
        var val = Convert.ChangeType(t1, typeof(bool?), null);
    }
}

I suspect you can only file a bug report, because you can perfectly pass the nullable as parameter, it is handled with errors.

grek40
  • 13,113
  • 1
  • 24
  • 50
  • Thanks! That indeed causes the issue. I filed a bug report: [link](https://mvvmlight.codeplex.com/workitem/7742). – Chris Dec 22 '16 at 13:08
  • Same issue here 4 months later. It doesn't seem it'll be corrected :( – Speuline Mar 27 '17 at 13:17
  • @Speuline I'm not quite sure whether the code that I referenced in the question is reflecting the current MVVM Light implementation. But if you get your hands on the current source and the problem is in it, you may just fix the issue yourself and be happy with it. – grek40 Mar 27 '17 at 14:25