wpf - 无法将类型 'MS.Internal.NamedObject' 的对象转换为自定义类型

标签 wpf casting prism observablecollection

我对WPF并不陌生,但我无法解决这个问题:

我使用ObservableCollection<MyCustomType>我绑定(bind)到ComboBox es,一切都像往常一样工作得很好,但在某些时候我需要更改集合的内容(我从数据库中检索一组新集合,它可能包含也可能不包含旧集合的一部分)。

现在添加或删除元素都是由 WPF 完成的,但如果您更改整个集合,我发现您必须为集合引发 PropertyChanged。

问题是有时它会崩溃,给我一个不太友好的异常。
我不确定到底是什么触发了崩溃,但如果我不触摸 View 并从数据库检索新的集合,它就不会崩溃。

这是一些代码:

    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,但这可能只是因为我从 ViewModel 上的 NotificationObject 继承。

感谢您对这个问题的任何帮助,

问候,

LK。

编辑:我认为问题来自 ComboBox,更具体地说,来 self 设置其属性的方式。

我将 ItemsSource 属性绑定(bind)到 ObservableCollection,为了决定选择哪个元素,我将 SelectedValue 绑定(bind)到 ObservableCollection 的项目的字段(ComboBox 嵌套在 ListView 中)。
我还设置了 SelectedValuePath (你明白了)。

我想当我更改第一个集合时,该设置就会失败。当我因为虚拟化而不触摸 View 时,它会保持平静(它最初是隐藏的)。

添加:

InnerException 为空。

消息: 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()

更多编辑:

我将问题隔离到单个 ComboBox 中,声明如下:

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

请注意anObjectID属性(property) SelectedValue来自ListView的 DataContext(此 ComboBox 正在显示该 ListView 的项目的一部分),而 anObjectIDSelectedValuePathDataContext.MyFirstCollection 中每一项的属性有。

这允许我为 ListView 的每个元素选择不同的 ComboBoxItem。

我希望我的解释很清楚,否则请在评论中告诉我,我会尽力澄清。

突破: ComboBox 将其 DataContext 设置为 {DisconnectedItem},这是所谓的 SentinelObjects 工作的结果,当两个集合之间存在绑定(bind)时,它会进行干预,如我的示例中所示。

这实际上是框架的官方错误,已在下一个版本中修复,请参阅此 MS Bug Page

有人知道解决方法吗?

编辑: 曾经有一个答案链接到我的博客,但是当我移动它时,人们对答案投了反对票。我已经厌倦了它,所以现在它准备好了就会回来。

最佳答案

  1. 无需为 MyObsCollection 调用 RaisePropertyChanged,因为 ObservableCollection 内部实现了 INotifiyProperty Changed。
  2. 我认为分配值时(在设置调用期间)会崩溃,当您尝试分配另一种类型的一种类型集合的集合时,就会发生这种情况。您必须创建 MyCustomType 的对象,并将其添加到 MyObsCollection,而不是直接将不同类型的集合分配给 MyObsCollection

如果可以发布整个代码或将对象分配或添加到 MyObsCollection 的代码段,那就太好了

关于wpf - 无法将类型 'MS.Internal.NamedObject' 的对象转换为自定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8227083/

相关文章:

c# - 如何在特定位置覆盖 WPF 控件

c++ - 如何为 MyClass** 传递 MyClass[][]?

将 struct * 转换为 int * 以便能够写入第一个字段

c# - 具有两个键和一个对象的最佳 C# 集合是什么?

c# - 如何插入多个GroupDescription?

wpf - 我还能如何在 View 模型的 View 中触发动画?

c# - 在 WPF 中共享 ObjectDataProvider

ios - 读取 info.plist : inferred to have type AnyObject which may be unexpected

c# - 在 PRISM 中导航到新 View 时如何传递对象?

mvvm - 属性更改时未执行委托(delegate)命令