Closed houstonhaynes closed 8 months ago
I also don't get the GeoMap visual on return to the View (so I'm assuming the init isn't getting sorted out). This is the error code that surfaces when I exit the app. Nothing shows up in console while it runs (other than the subs continuing to surface their activity) - this error only shows up after app exit. This may not be related - but I didn't want it to slip by in case it has some bearing on the view/VM state management and re-init on return to the view.
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at LiveChartsCore.GeoMap`1.Unload()
at LiveChartsCore.SkiaSharpView.Avalonia.GeoMap.GeoMap_DetachedFromVisualTree(Object sender, VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Visual.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Input.InputElement.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.Control.OnDetachedFromVisualTreeCore(VisualTreeAttachmentEventArgs e)
at Avalonia.Controls.TopLevel.HandleClosed()
at Avalonia.Controls.WindowBase.HandleClosed()
at Avalonia.Controls.Window.HandleClosed()
at Avalonia.Win32.WindowImpl.AppWndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
at Avalonia.Win32.WindowImpl.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)
This probably has to do with your view registration (Transient or Singleton).
The main thing to remember here is that Program.mkStoreWithTerminate
only works if your view is registered as Transient.
If you register a view as Transient
, its view model will be automatically Disposed when the view is unloaded, and a new VM will be instantiated anytime the view is loaded or reloaded.
(Terminate
, assuming Program.mkStoreWithTerminate
has been configured, is called when the VM is Disposed.)
The VM is only created once, and the VM is not Disposed when the view is unloaded.
So, Program.mkStoreWithTerminate
will do nothing here because the VM will never be disposed, and Terminate will never be called.
If you are using a Singleton view and you want to stop registrations, you will need to manually stop them yourself by subscribing to changes to the selected view.
Really interesting - I assumed non-Main views are transient by default.
At the moment, view/VM registrations have to be done manually, so there really isn't a default. However, I plan on adding some "register by convention" strategies in the future so that you don't have to manually wire-up all your view/vm pairs. Conventions meaning something like, auto-register "ProductView" to "ProductViewModel". That would probably be the default convention, but then you could change it to whatever you want, and specify the lifetime default as Transient or Singleton.
The Chart view works as a Singleton because of that "SetIsAutoUPdateChecked" logic that turns it off if you switch away from the view. I switched it to "Transient" and the AutoUpdate never shut off so I went back to switched in Program.mkStoreWithTerminate
and it worked.
So for my case it was copy-pasta as I copied and pasted the "ChartViewModel" Key in AppCompositionRoot.fs -- now that I've made them both Transient I won't make that mistake again. 😄
I'm not sure if this is me not understanding what should be happening, or if I have a case of improper "copy-pasta" but I just noticed that my subscriptions don't terminate even though I have it set with
Program.mkStoreWithTerminate this Terminate
https://github.com/JordanMarr/ReactiveElmish.Avalonia/assets/8174976/76f4c459-62d4-40d9-ad36-31fda23da44b
My understanding was that the "Terminate" was the magic pill that killed off those subs for me so I wouldn't have to do a full-retail state management effort that's there with the sub trigger "AutoUpdate" in the Chart View. Can you clue me in on what I might be missing in this picture?