3

Closed

RelayCommandGeneric.cs CanExecute raises InvalidCastException

description

Please consider this issue:
When we have parametrized RelayCommand and define own CanExecute method for example:
private RelayCommand<Window> _closeCommand
public RelayCommand<Window> CloseCommand
{
get
{
if(_closeCommand == null)
    _closeCommand = new RelayCommand(OnCloseCommand,OnCanCloseCommand);
return _closeCommand;
}
}

public void OnCloseCommand(Window wnd)
{
if(OnCloseCommand(wnd))
wnd.Close();
}
public bool OnCanCloseCommand(Window wnd)
{
return wnd != null;
}

After creating this command, binding it (to a button Command and necessarily CommandParameter properties for example) and building it
we will get designer error that will say: hey you have got InvalidCastException because
of unabling to cast Microsoft.Expression.WpfPlatform.InstanceBuilders.(here goes concrete class name,
it may be WindowInstance or something other that you trying to pass with CommandParameter property
of control) to the System.Windows.Window

Here goes example for resolving this issue in MVVM Light source code, I mark it with this
comment // <====== PLEASE CONSIDER FOR ADDING THIS CONDITION...
Could you please add something like: if(parameter is T) to the GalaSoft.MvvmLight(NET35)\RelayCommandGeneric.cs

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 is T) // <====== PLEASE CONSIDER FOR ADDING THIS CONDITION
                return _canExecute.Execute((T) parameter);
        }

        return false;
    }
With best regards!
Ashot Muradian, ashotmuradian@hotmail.com
Closed Oct 13, 2014 at 1:58 PM by lbugnion

comments

onovotny wrote Nov 17, 2012 at 5:11 PM

This has been fixed in the portable version here:
https://nuget.org/packages/Portable.MvvmLightLibs

lbugnion wrote Oct 13, 2014 at 10:57 AM

Fix will be available in V5.1

user78483 wrote May 11, 2016 at 5:05 PM

I'm currently on v5.3 and for Windows 10 builds greater than 14136 I get the following error. Could someone help me out?
Exception thrown: 'System.InvalidCastException' in aopp.exe
Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=Items[0].Selected; DataItem='CollectionViewGroupInternal' (HashCode=35847919); target element is 'ToggleButton' (Name='prodbut'); target property is 'IsChecked' (type 'Nullable`1') InvalidCastException:'System.InvalidCastException: Specified cast is not valid.
   at kompass.Converters.BillProductsGroupPriceMultiConverter.Convert(Object[] values, Type targetType, Object parameter, CultureInfo culture) in C:\Users\Converters\Converter.cs:line 15
   at System.Windows.Data.MultiBindingExpression.TransferValue()
   at System.Windows.Data.MultiBindingExpression.Transfer()
   at System.Windows.Data.MultiBindingExpression.InvalidateChild(BindingExpressionBase bindingExpression)
   at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange)
   at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
   at System.Windows.Data.BindingExpression.ScheduleTransfer(Boolean isASubPropertyChange)
   at MS.Internal.Data.ClrBindingWorker.NewValueAvailable(Boolean dependencySourcesChanged, Boolean initialValue, Boolean isASubPropertyChange)
   at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
   at MS.Internal.Data.ClrBindingWorker.OnSourcePropertyChanged(Object o, String propName)
   at MS.Internal.Data.PropertyPathWorker.OnPropertyChanged(Object sender, PropertyChangedEventArgs e)
   at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   at System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(Object sender, PropertyChangedEventArgs args)
   at System.Collections.ObjectModel.ReadOnlyObservableCollection`1.OnPropertyChanged(PropertyChangedEventArgs args)
   at System.Collections.ObjectModel.ReadOnlyObservableCollection`1.HandlePropertyChanged(Object sender, PropertyChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnPropertyChanged(PropertyChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.ClearItems()
   at System.Collections.ObjectModel.Collection`1.Clear()
   at MS.Internal.Data.CollectionViewGroupInternal.Clear()
   at MS.Internal.Data.CollectionViewGroupInternal.Clear()
   at MS.Internal.Data.CollectionViewGroupInternal.Clear()
   at MS.Internal.Data.CollectionViewGroupInternal.Clear()
   at System.Windows.Data.ListCollectionView.PrepareShaping()
   at System.Windows.Data.ListCollectionView.PrepareLocalArray()
   at System.Windows.Data.ListCollectionView.RefreshOverride()
   at System.Windows.Data.CollectionView.RefreshInternal()
   at System.Windows.Data.CollectionView.RefreshOrDefer()
   at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at kompass.Helpers.ItemsChangeObservableCollection`1.item_PropertyChanged(Object sender, PropertyChangedEventArgs e) in C:\ObservableCollection.cs:line 65
   at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
   at GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanged(String propertyName) in D:\GalaSoft\mydotnet\MVVMLight\source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (PCL)\ObservableObject.cs:line 198
   at kompass.Model.BillProductModel.set_Selected(Boolean value) in C:\Model.cs:line 81'
Exception thrown: 'System.ArgumentOutOfRangeException' in mscorlib.dll
Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll
Bypass prompt for source file: D:\GalaSoft\mydotnet\MVVMLight\source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (PCL)\Command\RelayCommandGeneric.cs.
Bypass prompt for source file: D:\GalaSoft\mydotnet\MVVMLight\source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (PCL)\Command\RelayCommandGeneric.cs.

lbugnion wrote May 11, 2016 at 5:48 PM

Hi,

Note that this issue is closed because it was fixed. Your comment points to something else altogether. It seems that you are having an exception within the BillProductsGroupPriceMultiConverter class. Try to set a breakpoint there and debug.

Thanks
Laurent