Невозможно передать объект типа "MS.Internal.NamedObject" в настраиваемый тип

Я не новичок в WPF, но я не могу понять эту проблему:

Я использую ObservableCollection<MyCustomType>, который я привязываю к ComboBox es, все работает отлично, как обычно, но в какой-то момент мне нужно изменить содержимое коллекции (я получаю новый набор из базы данных, который может или не может содержать часть старой).

Теперь добавление или удаление элементов выполняется WPF, но если вы измените всю коллекцию, я обнаружил, что вам нужно поднять PropertyChanged для коллекции.

Проблема заключается в том, что иногда это приводит к сбою, что дает мне не очень благоприятное исключение.
Я не уверен, что именно вызывает сбой, но если я не касаюсь представления и не получаю новый набор из БД, он не сбой.

Вот какой код:

    public const string MyObsCollectionProperty = "MyObsCollection";
    private ObservableCollection<MyCustomType> m_MyObsCollection;
    public ObservableCollection<MyCustomType> MyObsCollection
    {
        get { return m_MyObsCollection; }
        set
        {
            m_MyObsCollection = value;
            RaisePropertyChanged(MyObsCollectionProperty); // <-- Crashes here
        }
    }

Я получаю исключение: Unable to cast object of type 'MS.Internal.NamedObject' to type 'MyNameSpace.MyCustomType'

Обратите внимание, что это исключение происходит от Prism, но это, вероятно, только потому, что я наследую NotificationObject на моем ViewModel.

Я ценю любую помощь по этой проблеме,

С уважением,

LK.

EDIT: Я думаю, что проблема исходит от ComboBox и, более конкретно, от того, как я устанавливаю их свойства.

Я привязываю свойство ItemsSource к ObservableCollection и определяю, какой элемент выбрать, я привязываю SelectedValue к полю элемента ObservableCollection (ComboBox вложен в ListView).
Я также устанавливаю SelectedValuePath (вы получаете идею).

Я предполагаю, что когда я сменил первый сбор, адские перерывы проиграли в этой настройке. И это оставляет его в покое, когда я не касаюсь представления из-за виртуализации (сначала он скрыт).

Сложение:

InnerException - nulll.

Сообщение: Unable to cast object of type 'MS.Internal.NamedObject' to type 'CocoonV4.DAL.WcfServiceCocoonV4.DekoTemplate'.

   at Microsoft.Practices.Prism.Commands.DelegateCommand`1.<>c__DisplayClass6.<.ctor>b__3(Object o)
   at Microsoft.Practices.Prism.Commands.DelegateCommandBase.CanExecute(Object parameter)
   at Microsoft.Practices.Prism.Commands.DelegateCommandBase.System.Windows.Input.ICommand.CanExecute(Object parameter)
   at System.Windows.Interactivity.InvokeCommandAction.Invoke(Object parameter)
   at System.Windows.Interactivity.TriggerBase.InvokeActions(Object parameter)
   at System.Windows.Interactivity.EventTriggerBase.OnEvent(EventArgs eventArgs)
   at System.Windows.Interactivity.EventTriggerBase.OnEventImpl(Object sender, EventArgs eventArgs)
   at System.Windows.Controls.SelectionChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.Controls.ComboBox.OnSelectionChanged(SelectionChangedEventArgs e)
   at System.Windows.Controls.Primitives.Selector.InvokeSelectionChanged(List`1 unselectedItems, List`1 selectedItems)
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
   at System.Windows.Controls.Primitives.Selector.OnItemsChanged(NotifyCollectionChangedEventArgs e)
   at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Controls.ItemCollection.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e)
   at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list)
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Data.ListCollectionView.RefreshOverride()
   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.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.ClearItems()
   at System.Collections.ObjectModel.Collection`1.Clear()
   at CocoonV4.Modules.CocoonViewsVMs.ManageTemplateDekocastViewModel.SetAllowedDekos(IEnumerable`1 _NewAllowedDekos) in C:\Users\lkottmann\Documents\Visual Studio 2010\Projects\IAV-Cocoon\MAIN\CocoonV4\CocoonV4.Modules.RunningItem\CocoonViewsVMs\ManageTemplateDekocastViewModel.cs:line 83
   at CocoonV4.Modules.CocoonViewsVMs.ManageTemplateDekocastViewModel.LoadTemplates(Nullable`1 param) in C:\Users\lkottmann\Documents\Visual Studio 2010\Projects\IAV-Cocoon\MAIN\CocoonV4\CocoonV4.Modules.RunningItem\CocoonViewsVMs\ManageTemplateDekocastViewModel.cs:line 128
   at Microsoft.Practices.Prism.Commands.DelegateCommand`1.<>c__DisplayClass6.<.ctor>b__2(Object o)
   at Microsoft.Practices.Prism.Commands.DelegateCommandBase.Execute(Object parameter)
   at Microsoft.Practices.Prism.Commands.DelegateCommandBase.System.Windows.Input.ICommand.Execute(Object parameter)
   at System.Windows.Interactivity.InvokeCommandAction.Invoke(Object parameter)
   at System.Windows.Interactivity.TriggerBase.InvokeActions(Object parameter)
   at System.Windows.Interactivity.EventTriggerBase.OnEvent(EventArgs eventArgs)
   at System.Windows.Interactivity.EventTriggerBase.OnEventImpl(Object sender, EventArgs eventArgs)
   at System.Windows.Controls.SelectionChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.Controls.ComboBox.OnSelectionChanged(SelectionChangedEventArgs e)
   at System.Windows.Controls.Primitives.Selector.InvokeSelectionChanged(List`1 unselectedItems, List`1 selectedItems)
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(Object item, Boolean assumeInItemsCollection)
   at System.Windows.Controls.ComboBox.NotifyComboBoxItemMouseUp(ComboBoxItem comboBoxItem)
   at System.Windows.Controls.ComboBoxItem.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at CocoonV4.App.Main() in C:\Users\lkottmann\Documents\Visual Studio 2010\Projects\IAV-Cocoon\MAIN\CocoonV4\CocoonV4\obj\x86\Debug\App.g.cs:line 0
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Подробнее EDIT:

Я выделил проблему для одного ComboBox, как указано ниже:

<custom:CComboBox x:Name="cmbFirstDko"
                  ItemsSource="{Binding Path=DataContext.MyFirstCollection, ElementName=myViewName}"
                  SelectedValue="{Binding anObjectID, Mode=TwoWay}"
                  SelectedValuePath="anObjectID">

Обратите внимание, что свойство anObjectID в SelectedValue происходит из ListView DataContext (этот ComboBox отображает часть элемента этого ListView), тогда как anObjectID in SelectedValuePath ссылается на свойство, которое каждый элемент в DataContext.MyFirstCollection имеет.

Это позволяет мне выбрать другой ComboBoxItem для каждого элемента ListView.

Я надеюсь, что мои объяснения понятны, иначе скажите мне в комментариях, и я попытаюсь уточнить.

Прорыв: У ComboBoxes свой DataContext установлен на {DisconnectedItem}, это результат работы так называемых SentinelObjects, которые вмешиваются, когда есть привязка между двумя коллекциями, как в моем примере.

На самом деле это официальная ошибка в структуре, и она исправлена ​​для следующей версии, см. эту страницу ошибки MS

Кто-нибудь знает об обходном пути?

EDIT: Раньше был ответ, связанный с моим блогом, но пока я его перемещаю, люди отклоняли ответ. Я устал от этого, так что теперь он вернется, когда он будет готов.

Ответы

Ответ 1

  • Не нужно вызывать RaisePropertyChanged для MyObsCollection, потому что ObservableCollection внутренне реализует INotifiyProperty Changed.
  • Я думаю, что это сбой при назначении значения (во время заданного вызова), это произойдет, если вы попытаетесь назначить коллекцию одного типа нового типа. Вы должны создать объект MyCustomType и должны быть добавлены в MyObsCollection вместо прямого назначения коллекции другого типа MyObsCollection

Было бы здорово, если бы опубликовал весь код или фрагмент кода, где u назначил или добавлял объекты в MyObsCollection

Ответ 2

У меня такая же проблема только сейчас, и после удаления стиля static-ressource на ItemContainerStyle и определения его непосредственно под ListBox проблема исчезла.

У меня было свойство x: Name на элементах в DataTemplate, и, поскольку я их удалил, компилятор вообще не сделал этого. Поэтому я изменил способ, чтобы понять его.

Надеюсь, этот небольшой трюк поможет вам!