15

I'm experimenting with Windows 8 "Metro Styled Apps", MVVM Light and want to create a share target - so far so good. But if I'm in the OnShareTargetActivated method and want to add an item to an ObservableCollection I catch an InvalidCastException between class type and COM Object.

Das COM-Objekt des Typs "System.Collections.Specialized.NotifyCollectionChangedEventHandler" kann nicht in den Klassentyp "System.Collections.Specialized.NotifyCollectionChangedEventHandler" umgewandelt werden. Instanzen von Typen, die COM-Komponenten repräsentieren, können nicht in andere Typen umgewandelt werden, die keine COM-Komponenten repräsentieren. Eine Umwandlung in Schnittstellen ist jedoch möglich, sofern die zugrunde liegende COM-Komponente QueryInterface-Aufrufe für die IID der Schnittstelle unterstützt.

English version:

Unable to cast COM object of type 'System.Collections.Specialized.NotifyCollectionChangedEventHandler' to class type 'System.Collections.Specialized.NotifyCollectionChangedEventHandler'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

Now Im a Little bit confused and don't know how to handle this behavior properly.

MainViewModel main1 = new ViewModelLocator().Main;
MainViewModel main2 = new MainViewModel();
var conversation = new ConversationViewModel();
conversation.Messages.Add(new MessageViewModel { Image = img, Text = "Share" });
main1.Conversations.Add(conversation); // error InvalidCastException 
main2.Conversations.Add(conversation); // no error

Where img is a newly created BitmapImage

ViewModelLocator

public class ViewModelLocator
{
    /// <summary>
    /// Initializes a new instance of the ViewModelLocator class.
    /// </summary>
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<MainViewModel>();
        SimpleIoc.Default.Register<UserViewModel>();
        SimpleIoc.Default.Register<UriViewModel>();
    }

    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }

    //...
}

Stack Trace:

at System.StubHelpers.StubHelpers.GetCOMIPFromRCW_WinRTDelegate(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection
1.InsertItem(Int32 index, T item) at System.Collections.ObjectModel.Collection`1.Add(T item)

Philipp
  • 15,377
  • 4
  • 35
  • 52
  • 1
    Hope you don't mind. I've added the English version of the same exception message and stack trace to the question. Did you ever figure this out? – Daniel Ballinger Apr 22 '13 at 09:34
  • The error is about the calling context of the application - the two objects have the same type, but one is a com object(share) and the other a ".net" object(ViewModelLocaltor().Main) - mixim them together results in such problems.. – Philipp Apr 22 '13 at 11:24
  • I just ran into the same issue. Has anyone found a resolution? – mztan Apr 23 '13 at 03:01
  • 4
    It'd help to see how you are creating the img object. – SWalters Apr 24 '13 at 04:21
  • Would you post the code from your ViewModelLocator class for the "Main" property – Faster Solutions Apr 24 '13 at 16:13
  • Added the ViewModelLocator code - what I did to solve my Problem is, to store the updates i did in the isolatedstorage and checked this file when the app got the focus again. That solved my problem – Philipp Apr 26 '13 at 19:19
  • Have you tried this, return ServiceLocator.Current.GetInstance() as MainViewModel; – Jegan May 09 '13 at 09:32
  • Are your view-models in a portable class library? – PatrickV Aug 04 '13 at 23:33
  • How does your Conversations property declaration look? – Avram Tudor Aug 07 '13 at 12:12

1 Answers1

1

Instead of explicit casting use the "as" conversion, it sounds like the instance returned by the service locator is not a MainViewModel object, change that line to

return ServiceLocator.Current.GetInstance() as MainViewModel;

It may behave differently, if the instance is not a MainviewModel then it will return null, this will help you debug why the instance returned null from the service locator.

Irshad
  • 3,071
  • 5
  • 30
  • 51
Jegan
  • 1,227
  • 9
  • 16