SingleActiveRegion and KeepAlive

Topics: Prism v4 - Silverlight 4
Dec 3, 2010 at 5:57 AM

Hi,

I have a Shell page that has a ContentControl with a Region marked on it call MainRegion. I load a module into the region using RequestNavigate. All this is done through MEF. The module accepts a parameter which I pass as  UriQuery and it is picked up correctly by the view model (which implements INavigationAware) of the view being loaded.

The view model looks something like this

[Export(typeof(IViewModel))]
[RegionMemberLifetime(KeepAlive = false)]
public class ViewModel : IViewModel, INavigationAware
{
public void OnNavigatedTo(NavigationContext navigationContext)
        {
            Id = Convert.ToInt32(navigationContext.Parameters["Id"]);
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }
}

And the view looks like this

[Export("MyView")]
[PartCreationPolicy(CreationPolicy.NonShared)] // want the view to be created each time
public class MyView : UserControl
{
     public MyView()
     {
          InitializeComponent();
     }

     [Import]
     public IViewModel Model
     {
         get { return (IViewModel)DataContext; }
         set { DataContext = value; }
     }
}

It all works fine so far. Now when I click on a link in my view which simply calls the HtmlPage.Window.Navigate to the same module with a different parameter, the MyView doesnt seem to get recreated. It just goes into the OnNavigated event in the ViewModel and repopulates the data in it with the new Id passed.

I noticed that in the RegionManager, the current MyView was in the ActiveViews list. I thought when we set KeepAlive false in a SingleActiveRegion (ContentControlRegionAdapter) it will deactivate the view and remove it from the region as well. But it doesnt seem to do that.

Has anyone faced this issue before ? I'm kind of stuck at the moment.

As a workaround I'm having to do this in the OnNavigatedFrom

public void OnNavigatedFrom(NavigationContext navigationContext)
{
     var mainRegion = _regionManager.Regions["MainRegion"];
     mainRegion.Deactivate(mainRegion.ActiveViews.SingleOrDefault());
}

By doing this the MyViwe gets recreated each time I navigate to it.

Developer
Dec 3, 2010 at 6:05 PM

Hi,

The behavior you are reporting is by design. Based on my understanding, you are trying to create a new instance of your view every time you navigate into it. Setting the KeepAlive property to false will result in the view being removed once deactivated, but will not remove the view by itself. Therefore, it is ok to deactivate your active view in the OnNavigatedFrom method. For more information about this region behavior, you can check this article from the Prism MSDN documentation.

Also, take into account that you cannot load modules, but rather views into regions. You can find more information about this in this thread.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Dec 4, 2010 at 12:56 PM

Hi Guido,

Thanks for the response. That helps. Of course when I referred to loading a module in region I meant loading a view in the Module.

I'm going to take the path of deactivating the view when navigating to it again as I need that behavior.

Mar 16, 2012 at 9:27 AM

Hi Guido,

Sorry to open up this thread again. As per the above discussion we went with view deactivation from the OnNavigatedFrom of the view model. This however results in the Loaded event of the view to be called again after the OnNavigatedFrom, and results in intermediate errors with region creation, i.e. the region with the given name already exists in the region collection. Of course this doesnt happen each time, but does happen quite often.

By commenting out the deactivation bit, we dont get that error anymore. However we lose the behavior we wanted, i.e. recreation of view and viewmodel everytime. Now we are planning to resort to resetting values in the viewmodel each time we get into it consequtively for different parameters.

We have a sample app reproducing this issue, but I cannot upload it from my workplace. Will try and get something for you guys to check soon.

Thanks.