Well! try this. it is a bit long but tested
In short:
you need to do a couple of event registers to distinguish between what is currently UIViews are opened and what are closed. So we need to store the currently opened UIViews ids and keep adding newly created/opened ones. as well as to remove those which are closed.
Also, we need to use Revit IdlingEvent to trigger an event, since Revit is not busy, meaning all views are now closed.
Hence, when Revit is in Idle state we compare the currently opened UIViews against what we stored then we run our Math.
One drawback of the below, if you closed a view that is not the current view. the below algorithm won't work. but eventually will work when you switch to another view. but I trust you can cover this drawback part.
see the below code and let us know if something is not clear.
as a hint, you can start registering all these events on Revit Start at the IExternalApplication class. or via IExternalCommand depends on how your strategy is.
ViewClosed_Event Workaround
Summary:
1. Register DocumentOpened all Available UIViews Id
2. Register on ViewActivating To store new created View to the ViewIds store list
3. Register on ViewActivated the comparison between current opened Views against the closed using the power of Idling event
4. unregister all events once you no more need that
Detail:
1. Register DocumentOpened all Available UIViews Id
m_uiapp.Application.DocumentOpened += delegate{
viewids = m_uidoc.GetOpenUIViews().Select(o => o.ViewId).ToList();
};
2. Register on ViewActivating To store new created View to the ViewIds store list
m_uiapp.ViewActivating += M_uiapp_ViewActivating;
private void M_uiapp_ViewActivating(object sender, Autodesk.Revit.UI.Events.ViewActivatingEventArgs e)
{
if (!viewids.Contains(e.NewActiveView.Id))
viewids.Add(e.NewActiveView.Id);
}
3. Register on ViewActivated the comparison between current opened Views against the closed using the power of Idling event
UT_Rvt.m_uiapp.ViewActivated += M_uiapp_ViewActivated;
private void M_uiapp_ViewActivated(object sender, Autodesk.Revit.UI.Events.ViewActivatedEventArgs e)
{
UT_Rvt.m_uiapp.Idling += M_uiapp_Idling;
}
private void M_uiapp_Idling(object sender, Autodesk.Revit.UI.Events.IdlingEventArgs e)
{
var ids = m_uidoc.GetOpenUIViews().Select(o => o.ViewId);
List<ElementId> closedids = new List<ElementId>();
foreach (var id in viewids)
{
if (ids.Contains(id)) continue;
ViewIsClosed(id);
closedids.Add(id);
}
foreach (var id in closedids)
{
viewids.Remove(id);
}
// Stop Idling from repeating itself, since we are done here.
m_uiapp.Idling -= M_uiapp_Idling;
}
private void ViewIsClosed(ElementId id)
{
var view = m_doc.GetElement(id) as View;
TaskDialog.Show("Closed", $"View is Closed {id} {view.ViewName}");
}
and finally, don't forget to unregister all events once you no more need that
private void UnregisterEvents()
{
m_uiapp.Application.DocumentOpened -= Application_DocumentOpened;
m_uiapp.ViewActivating -= M_uiapp_ViewActivating;
m_uiapp.ViewActivated -= M_uiapp_ViewActivated;
}
Hope this helps.
Moustafa Khalil