Skip to content

[BUG] Multiple view is not supported #2183

@KAS1990

Description

@KAS1990

Describe the bug
My Windows 10 UWP app has multiple views (i use ProjectionManager). My ParentViewModel contains SourceCache. In both views (MainView, SecondaryScreenView) i use the same instance of ParentViewModel. To show ChildViewModel's list i use ListView
MyListView.ItemsSource = ParentViewModel.ChildrenReadOnlyObservableCollection.
MyListViews has the same ItemTemplate:

<DataTemplate>
  <reactiveui:ViewModelViewHost ViewModel="{Binding}" ViewContract="MyContract" />
</DataTemplate>

Sometimes when i scrolling one of MyListViews exception is fired:
Exception thrown: 'System.Runtime.InteropServices.COMException' in System.Private.CoreLib.dll
WinRT information: Element not found.
Stack trace:
System.Private.CoreLib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 154 C#
System.Private.CoreLib.dll!System.Threading.TimerQueueTimer.CallCallback() Line 608 C#
System.Private.CoreLib.dll!System.Threading.TimerQueueTimer.Fire() Line 572 C#
System.Private.CoreLib.dll!System.Threading.TimerQueue.FireQueuedTimerCompletion(object state) Line 353 C#
System.Private.CoreLib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Line 948 C#
System.Private.CoreLib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 582 C#
System.Private.CoreLib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Line 882 C#

This exception is not catched by Application.UnhandledException and TaskScheduler.UnobservedTaskException, and chrashes my app anyway. After some days of investigations i found the reason of this behavior. It is ViewModelViewHost and PlatformOperations. When ViewModelViewHost.ViewModel has been changed ViewModelViewHost calls PlatformOperations.GetOrientation() to get default view contract. This function calls
Windows.Graphics.Display.DisplayInformation.GetForCurrentView().CurrentOrientation.ToString() to get this info.
What is happening is that because GetForCurrentView is being called from the timer thread can't resolve the view and retrieve it's settings, then the property tries to read the data and fails as there are no settings. (see https://stackoverflow.com/questions/45624375/element-not-found-when-trying-to-execute-a-code-every-time-a-timer-ticks).
I tried to register MyPlatformOperations class which return null from function GetOrientation, but IPlatformOperations is internal interface, that's why i cannot deliver MyPlatformOperations from IPlatformOperations. Then i tried to get IPlatformOperations from assembly by refrection
Locator.CurrentMutable.RegisterConstant(new MyPlatformOperations(), typeof(ReactiveObject).Assembly.DefinedTypes.First(type =>type.FullName == "IPlatformOperations").AsType()).
But after that RoutingState constructor is failed on app start.
Maybe i make a mistake on registration?
Then i tried to solve my problem by switching from Binding in ListView to manually managing items in ListView: observing SourceCache changings and calling MyListView.Items.Add/Remove. But sometimes my app is crashing too after that changes. Please help me!!!
Environment

  • OS: Windows 10 Pro 1809 17763.737
  • Version ReactiveUI 10.2.2 and ReactiveUI.Fody 10.2.2.
  • Device: PC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions