Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass Nullable<Boolean> value to CommandParameter?

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.

like image 810
Chris Avatar asked Dec 22 '16 10:12

Chris


1 Answers

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.

like image 123
grek40 Avatar answered Oct 29 '22 20:10

grek40