1
votes

I have a view (I'll call it MainView) that contains a TabControl. The views that make up the TabItems are created using prism view discovery in MainView's ViewModel. Each of the views that are "tabs" have some cleanup that needs to be done (detaching event handlers, etc.) when I'm done with the tab control (i.e. during the MainView's Unloaded event). However, I can't do the cleanup with the Tab views' Unloaded event, as this is called when just switching tabs.

MainView is calling a method on its ViewModel when Unloaded fires, but that ViewModel does not have a reference to the Views or ViewModels that make up the tabs due to the way those views are registered. What is the proper way to clean up after my "discovered" tab views?

3

3 Answers

1
votes

I have a similar situation, but we are using a Dock control where the views are loaded using Prism. So, in the Shell Views code behind unloaded event, we loop over the open Views and get the ViewModel for each view. All of our ViewModels inherit from a base ViewModel that has a virtual bool CanClose method that returns whether the view can close or not. The base ViewModel just returns true. This method is used to check if there are validation errors, unsaved changes, etc. So, then you would override this method and perform the clean up your talking about. If all of the views return true, then you could call the main shell viewmodel unload, if not then you can cancel the main view from unloading.

foreach (var doc in dockManager.Documents)
{
    if (!doc.CanClose())
    {
        e.Cancel = true;
        return;
    }
}
1
votes

We ended up using a message via the EventAggregator to clean up the sub-views.

0
votes

I use Prism navigation in my application, and faced the same issue. To address the problem, in the parent view model, in the OnNavigatedFrom method, I close all the views in the TabControl's region:

public class ParentViewModel : INavigationAware
{
    ...
    public void OnNavigatedFrom(NavigationContext navigationContext)
            {
        var region = RegionManager.Regions["TabsRegion"];
        foreach (var view in region.Views)
            region.Remove(view);
    }
}