InvalidCastException с целью совместного использования в Windows 8

Я экспериментирую с Windows 8 "Metro Styled Apps", MVVM Light и хочу создать целевой ресурс - пока это так хорошо. Но если я в методе OnShareTargetActivated и хочу добавить элемент в ObservableCollection, я поймаю InvalidCastException между типом класса и COM-объектом.

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-Компонентен рецензент, können nicht in andere Typen umgewandelt werden, die keine COM-Komponenten repräsentieren. Eine Umwandlung в Schnittstellen ist jedoch möglich, sofern die zugrunde liegende COM-Komponente QueryInterface-Aufrufe für die IID der Schnittstelle unterstützt.

Английская версия:

Невозможно передать COM-объект типа "System.Collections.Specialized.NotifyCollectionChangedEventHandler" в тип класса "System.Collections.Specialized.NotifyCollectionChangedEventHandler". Экземпляры типов, представляющих COM-компоненты, нельзя отбрасывать типам, которые не представляют COM-компоненты; однако они могут быть переданы в интерфейсы, если базовый COM-компонент поддерживает вызовы QueryInterface для IID интерфейса.

Теперь я немного немного смущен и не знаю, как правильно обращаться с этим поведением.

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

Где img - созданный недавно 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>();
        }
    }

    //...
}

Трассировка стека:

в System.StubHelpers.StubHelpers.GetCOMIPFromRCW_WinRTDelegate (Объект objSrc, IntPtr pCPCMD, IntPtr & ppTarget)
   в System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Объект отправителя, NotifyCollectionChangedEventArgs e)
   в System.Collections.ObjectModel.ObservableCollection 1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection
1.InsertItem(Int32 index, T item) в System.Collections.ObjectModel.Collection`1.Add(T пункт)

Ответы

Ответ 1

Вместо явного литья используйте преобразование "as", это похоже на то, что экземпляр, возвращаемый локатором службы, не является объектом MainViewModel, измените эту строку на

return ServiceLocator.Current.GetInstance() as MainViewModel;

Это может вести себя по-другому, если экземпляр не является MainViewModel, тогда он вернет null, это поможет вам отладить, почему экземпляр возвратил null из локатора службы.