2011-11-22 13 views
15

Tôi không phải là mới để WPF, nhưng tôi không thể tìm ra vấn đề này:Không thể cast đối tượng của loại 'MS.Internal.NamedObject' để loại tùy chỉnh

tôi sử dụng một ObservableCollection<MyCustomType> mà tôi liên kết với ComboBox es , tất cả đều hoạt động tốt như thường lệ, nhưng tại một thời điểm nào đó tôi cần phải thay đổi nội dung của bộ sưu tập (tôi lấy một bộ mới từ cơ sở dữ liệu, có thể hoặc không thể chứa một phần của bộ cũ).

Bây giờ việc thêm hoặc xóa các phần tử đều do WPF thực hiện, nhưng nếu bạn thay đổi toàn bộ bộ sưu tập tôi thấy bạn phải tăng PropertyChanged cho bộ sưu tập.

Vấn đề là đôi khi sự cố cho tôi một ngoại lệ không thân thiện.
Tôi không chắc chắn về những gì chính xác kích hoạt sự cố, nhưng nếu tôi không chạm vào Chế độ xem và truy xuất tập hợp mới từ DB, nó sẽ không bị lỗi.

Dưới đây là một số mã:

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 
     } 
    } 

tôi nhận được ngoại lệ: Unable to cast object of type 'MS.Internal.NamedObject' to type 'MyNameSpace.MyCustomType'

Xin lưu ý rằng ngoại lệ này xuất phát từ Prism, nhưng nó có lẽ chỉ vì tôi kế thừa từ NotificationObject trên ViewModel của tôi.

Tôi đánh giá cao bất kỳ giúp đỡ về vấn đề này,

Kính trọng,

LK.

EDIT: Tôi nghĩ rằng vấn đề xuất phát từ ComboBox và cụ thể hơn, từ cách tôi đặt thuộc tính của họ.

Tôi ràng buộc thuộc tính ItemsSource với ObservableCollection và quyết định chọn phần tử nào, tôi liên kết SelectedValue với trường của mục của ObservableCollection (ComboBox được lồng trong một ListView).
Tôi cũng đặt SelectedValuePath (bạn có ý tưởng).

Tôi đoán khi tôi thay đổi bộ sưu tập địa ngục đầu tiên bị mất trên thiết lập đó. Và nó để lại nó trong hòa bình khi tôi không chạm vào xem vì ảo hóa (nó được ẩn lúc đầu).

ADDITION:

Các InnerException là nulll.

nhắn: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() 

More EDIT:

tôi đã phân lập được vấn đề để một ComboBox đơn declarated như sau:

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

Xin lưu ý rằng anObjectID bất động sản trong SelectedValue xuất phát từ DataContext của ListView (ComboBox này hiển thị một phần của một mục của ListView đó), trong khi anObjectID trong SelectedValuePath đề cập đến thuộc tính mà mỗi mục trong DataContext.MyFirstCollection có.

Điều này cho phép tôi chọn một ComboBoxItem khác cho mỗi phần tử của ListView.

Tôi hy vọng lời giải thích của tôi rõ ràng, nếu không hãy cho tôi biết trong phần nhận xét và tôi sẽ cố gắng làm rõ.

Đột phá: Các ComboBoxes có DataContext của họ thiết lập để {DisconnectedItem}, đây là kết quả của công việc của cái gọi là SentinelObjects mà can thiệp khi có một ràng buộc giữa 2 bộ sưu tập, như trong ví dụ của tôi.

Đó là thực sự đã chính thức là một lỗi của khuôn khổ này, và nó đã được cố định cho phiên bản tiếp theo, hãy xem MS Bug Page

Có ai biết một workaround?

EDIT: Đã từng là câu trả lời liên kết đến blog của tôi, nhưng trong khi tôi di chuyển nó, mọi người đã bỏ phiếu bình chọn. Tôi đã bị bệnh vì vậy bây giờ nó sẽ trở lại khi nó đã sẵn sàng.

+0

Tôi sẽ không đề xuất một setter trên thuộc tính 'ObservableCollection', tôi thường sử dụng trường' readonly' và thuộc tính chỉ với getter. –

+0

Bạn có thể đăng cách RaisePropertyChanged này được triển khai không?Tại sao nó không phải là một chuỗi? – MBen

+0

@MBen: MyObsCollectionProperty là một chuỗi. –

Trả lời

2
  1. Không cần gọi RaisePropertyChanged cho MyObsCollection, bởi vì thực hiện nội bộ ObservableCollection INotifiyProperty đã thay đổi.
  2. Tôi nghĩ rằng nó là Crashing trong khi gán giá trị (trong khi thiết lập cuộc gọi), điều này sẽ xảy ra khi bạn cố gắng chỉ định một bộ sưu tập của một loại bộ sưu tập loại khác. Bạn phải tạo đối tượng của MyCustomType và phải được thêm vào MyObsCollection thay vì trực tiếp chỉ định một bộ sưu tập loại khác cho MyObsCollection

Sẽ thật tuyệt vời nếu có thể đăng toàn bộ mã hoặc đoạn mã nơi bạn chỉ định hoặc thêm các đối tượng vào MyObsCollection

2

Tôi vừa gặp vấn đề vừa nãy, và sau khi tôi loại bỏ Kiểu phân luồng tĩnh trên ItemContainerStyle và xác định nó trực tiếp bên dưới ListBox, vấn đề đã biến mất.

Tôi đã có x: Tên thuộc tính trên các phần tử trong DataTemplate, và vì tôi đã xóa chúng, bộ compilator đã không làm cho nó ở tất cả, có lẽ. Vì vậy, tôi đã thay đổi một cách để làm cho nó có ý nghĩa.

Hy vọng mẹo nhỏ này sẽ giúp ích cho bạn!