New behaviors for Dockable panels using WpfElementHost in Rhino 6

While upgrading our WPF plug-ins to Rhino 6, we’re seeing a significant change in how the WpfElementHost is working that we thought would be worth documenting. In Rhino 5, the WpfElementHost class constructor seems to be called just once, which is the first time that the dockable panel is opened. In Rhino 6, we notice now that every time a document is changed, if the dockable panel is opened, the WpfElementHost constructor is is called. This occurs before any document-related event is fired (so before NewDocument, BeginOpenDocument, EndOpenDocument).

We also noticed that view models bound to the WpfElementHost don’t appear to be disposed at this point. So we have a RhinoEntry class that manages how our plug-ins interact with selection, object creation/deletion, and document related events. What we’ve found is that instances of this class bound to our view models remain alive and well even after new models are bound to the user control, and their event listening continues. So if our users change documents multiple times, as many of our RhinoEntry classes exist behind the scenes. We’ve adapted for this by relocating this class as a static class in our plug-in, but thought it was worth noting this change in behavior.

Dave,

I will take a look at the host and see what I can do about supporting IDisposable when destroying the WpfElementHost.

The framework supports panel classes with a constructor taking no arguments or a constructor taking a uint representing the document runtime serial number associated with the panel. In addition you can register the panel as a PanelType.System which will only get created once per Rhino session when running on Windows.

Thanks John, good to know.

I’m finding that not only is the WpfElementHost being recreated each time a document changes, but if the panel is closed and reopened as well. The repeated creation of the underlying ViewModel when the panel is closed and re-opened is really proving problematic.

Could you maybe help me better understand how I go about registering my WpfElementHost as a PanelType.System to ensure that it’s only created once per Windows session? I’ve tried this overload method, supplying a Rhino.UI.PanelType.System to the PanelType, but it’s still being recreated on both document changes and the panel being re-opened.

I ran some test and the PanelType.System flag appears to have been broken in a service release. I logged a bug regarding this and will look into it soon.

1 Like

I fixed the system panel bug and also made sure the WPF host calls Dispose as appropriate for the elements view model. The fix will be in next weeks Rhino 6.6 release.

3 Likes

Awesome! Thanks John.

FYI: a client just installed the latest update for Rhino 9 (Version 6 SR7 (6.7.18199.22081, 07/18/2018)) and it broke our plug-in.

The plug-in is listening to Rhino.UI.Panels.Show to access our control host ViewModel using Rhino.UI.Panels.GetPanels You should probably know that in this last update, the e.Document and e.DocumentSerialNumber properties of the Rino.UI.ShowPanelEventArgs are both now returning null values, which led to the failure for it to return our panel host. I am working around it by setting the document of our Rhino entry class at the RhinoDoc.EndOpenDocument event and using that to look for my host…but I’m guessing it wasn’t deliberate for the PanelEventArgs to lose that intelligence. And now we’re redeploying in a panic to boot. :frowning:

Logged in RH-47494. We are looking into this now. This seems like a major regression to me.

RH-47494 is fixed in the latest Service Release - we put out a new version of 6.7 to fix this.