In my WPF
application which makes use of ReactiveUI
, I've noticed an area of poor performance.
I have a view-model which contains a lot of other lightweight view-models (think 30ish). These nested view-models are simple, usually representing a button each. They're all displayed within a user control, inside an ItemsControl
which is wired using ReactiveUI's OneWayBind
. This means that each item is displayed using ViewModelViewHost.
So, the problem
On my powerful desktop PC, when I navigate to this view-model, there is a noticable delay between pressing the "go-to-view-model" button and the view changing, around 0.5 seconds. When I run the same software on a Power-PC, the delay is nearly 4 seconds. This is a pretty big issue from an UX point of view.
What I've learned
I tried profiling and debugging my code for a long time, and found no problem areas. Zilch (note: using JustMyCode in VS so ReactiveUI didn't show up). I did however, find a way to remove the issue. Instead of binding to the ItemsControl.ItemSource
with OneWayBind
, I did so in XAML, as such:ItemSource={Binding MyViewModels}
and setting the DataTemplate
manually. This results in a much quicker transition.
When you bind with OneWayBind
with an ItemsControl
, a ViewModelViewHost
is automatically created for you, and the ViewLocator
is used to find the view for your view-model. I'm assuming this is very slow for some reason.
Question
Is anyone aware of how I can get around this performance hit without having to manually define lots and lots of data-templates for an ItemsControl? If I have view-models of view-models of view-models, then things tend to get ugly very quickly. From my past experiences with Caliburn.Micro
, the view-location conventions were very quick, so I'm also wondering if I'm not quite using ReactiveUI
properly, and that there is an alternative approach which is quicker.
Thank you.
TLDR;
ViewModelViewHost
as a DataTemplate
for ~30 view-models causes views to be very sluggish when initially loaded, leaving the UI to look as if it has crashed. Is there any way to avoid this?