I have also run into this issue. In our case, the issue manifests itself when:
- using WebView2, new Microsoft control that supports HTML5 (could not use CEFSharp or any other for our use case)
- when opening/navigating to a second document; when closing all active documents
The solution was to handle all those cases manually and make sure to dispose of the active webView control and recreated it anew when the need arose. I made use of a few Revit events that would point to the exact moment when a new document was being opened and when where a document was about to close. For posterity, here is the code for our use case.
private MyPage page = null;
//set default URL state
private Uri urlState = new Uri("https://microsoft.com");
private bool IsInitiated = false;
private bool IsVisible = false;
private Document document;
public void SetupDockablePane(DockablePaneProviderData data)
{
data.FrameworkElementCreator = this as IFrameworkElementCreator;
data.InitialState = new DockablePaneState();
data.InitialState.MinimumWidth = 300;
data.VisibleByDefault = false;
data.EditorInteraction = new EditorInteraction(EditorInteractionType.KeepAlive);
data.InitialState.DockPosition = DockPosition.Right;
data.InitialState.TabBehind = DockablePanes.BuiltInDockablePanes.ProjectBrowser;
}
public FrameworkElement CreateFrameworkElement()
{
page = new MyPage();
return page;
}
// Close the current webView when opening a new document
public void A_VActivating(object sender, ViewActivatingEventArgs e)
{
RegisterDocument(e.NewActiveView.Document);
if (e.NewActiveView.Document == null || e.CurrentActiveView.Document.Title != e.NewActiveView.Document.Title)
{
Close();
}
}
// Register to the DocumentClosing event of the current document
private void RegisterDocument(Document document)
{
try
{
this.document.DocumentClosing -= new EventHandler<DocumentClosingEventArgs>(D_DClosing);
}
catch (Exception) { }
this.document = document;
this.document.DocumentClosing += new EventHandler<DocumentClosingEventArgs>(D_DClosing);
}
// Create a new webView and navigate to the current url
public void A_VActivated(object sender, ViewActivatedEventArgs e)
{
if(e.PreviousActiveView.Document.Title != e.CurrentActiveView.Document.Title)
{
this.page.Navigate(urlState);
}
}
// Save the current url and kill the webView
public void Close()
{
this.urlState = this.page.webView.Source;
this.page.webView.Dispose();
}
// If we are about to close down the very last document, kill the webView
internal void D_DClosing(object sender, DocumentClosingEventArgs e)
{
if(e.Document.Application.Documents.Size == 1)
{
this.document.DocumentClosing -= new EventHandler<DocumentClosingEventArgs>(D_DClosing);
this.document = null;
this.IsInitiated = false;
Close();
}
}
// Navigate for the first time (delay until dockable pane is on screen)
internal void A_DFVChanged(object sender, DockableFrameVisibilityChangedEventArgs e)
{
this.IsVisible = e.DockableFrameShown;
if (IsVisible && page != null && !IsInitiated)
{
this.page.Navigate(urlState, 1000);
this.IsInitiated = true;
}
}
Oh, one more thing that could be of some value - the example code provided by the Autodesk Dev team was helpful, but also a bit confusing - you don't have to use a command to register a dockable pane in the application. This is what I do and it works fine.
private static void CreateDockablePane(UIControlledApplication a)
{
bpage = new BrowserPage();
var dpid = new DockablePaneId(new Guid("3E545790-5D3B-475D-9280-81F4F0640C66"));
a.RegisterDockablePane(dpid, "Architype Learn", bpage as IDockablePaneProvider);
a.ViewActivating += new EventHandler<ViewActivatingEventArgs>(bpage.A_VActivating);
a.ViewActivated += new EventHandler<ViewActivatedEventArgs>(bpage.A_VActivated);
a.DockableFrameVisibilityChanged += new EventHandler<DockableFrameVisibilityChangedEventArgs>(bpage.A_DFVChanged);
}
public Result OnStartup(UIControlledApplication a)
{
MyApplication = a; //Initialize MyApplication that will be used by the class
AddRibbonPanel(a);
CreateDockablePane(a);
return Result.Succeeded;
}
It's a mouthful but might be useful for someone down the road.