Error: The region does not contain the specified view

Topics: Prism v4 - WPF 4
Sep 20, 2012 at 7:36 PM

I am using the following code to remove a specific view from a region.  There is only this one view in the region, but when it is removed, I get an error message that says, "The region does not contain the specified view.  Parameter name: view".

          try
          {
              // Get the regions views
              var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
              List<object> views = new List<object>();
              List<object> removeViews = new List<object>();

              if (regionManager.Regions["WorkspaceRegion"] != null)
              {
                  foreach (object view in regionManager.Regions["WorkspaceRegion"].ActiveViews)
                  {
                      views.Add(view);
                  }
                  for (int i = 0; i < views.Count; i++)
                  {
                      if (views[i].GetType().Name == "ModuleEquipmentTabs")
                          removeViews.Add(views[i]);
                  }

                  if (removeViews.Count > 0)
                      for (int i = 0; i < removeViews.Count; i++)
                      {
                          regionManager.Regions["WorkspaceRegion"].Remove(removeViews[i]);
                      }
              }
          }
          catch (Exception x)
          {
            MessageBox.Show(x.Message.ToString());
          }
Developer
Sep 21, 2012 at 12:08 PM
Edited Sep 21, 2012 at 12:26 PM

Hi,

Based on my understanding, this behavior could be caused if you are implementing the IRegionMemberLifetime interface in your views, and returning false in its KeepAlive property. Which could cause that when you remove the view, the region manages to remove the view successfully. However, as your view implements IRegionMemberLifetime, it gets notified that it's not the active view anymore and then, as the KeepAlive property returns false, Prism tries to remove the view from the region again. For more information about this and possible approaches on how to avoid this kind of behavior I believe you could check the following related resources:

I hope you find this helpful,

Agustin Adami
http://blogs.southworks.net/aadami

Sep 21, 2012 at 2:02 PM

Agustin, thank you for your reply.  Your explanation sounds plausible, so followed the link and subsequently changed my code to deactivate the view instead of removing it.  However, I then got an error message which says, "Deactivation is not possible in this type of region".  Of course, the region is of type "ItemsControl" and does not allow deactivation.  So I think that I could change my code back to my original solution and ignore the error when it is trapped in my "catch".  Do you know of any unforseen problems with this solution, or do you know of a solution that is a bit more elegant?

Developer
Sep 21, 2012 at 4:21 PM
Edited Sep 21, 2012 at 4:23 PM

Hi,

Have you considered changing the RegionMemberLifetimeBehavior class as mentioned in the work item in the second link (Silverlight - Add/Remove view - ArgumentException), as far as I know this approach should also work for WPF applications, and seems to be a more elegant solution.

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Sep 21, 2012 at 6:57 PM
Edited Sep 21, 2012 at 7:05 PM
I suppose the fix in my app would go something like this?
 if (removeViews.Count > 0)
     for (int i = 0; i < removeViews.Count; i++)
     {
           if (!ShouldKeepAlive(removeViews[i]))
          regionManager.Regions["WorkspaceRegion"].Remove(removeViews[i]);
     }
... but the linked example references Region instead of regionManager:
private bool ShouldKeepAlive(object inactiveView)
 {
 if (this.Region.Views.Contains(inactiveView))
 {
 IRegionMemberLifetime lifetime = GetItemOrContextLifetime(inactiveView);
 if (lifetime != null)
 {
 return lifetime.KeepAlive;
 }

 RegionMemberLifetimeAttribute lifetimeAttribute = GetItemOrContextLifetimeAttribute(inactiveView);
 if (lifetimeAttribute != null)
 {
 return lifetimeAttribute.KeepAlive;
 }
 }

 return true;
 }
How would I make that conversion?
Developer
Sep 25, 2012 at 3:08 PM

Hi,

Take into account that the second approach aims to change the default Prism RegionMemberLifetimeBehavior, this behavior is applied to all regions and changing this approach like mentioned in the work item should fix the second removal of the view from the region when using the remove method. In other words, once you applied the changes in the work item and no additional logic, you should be able to use the remove method like in your first post without receiving the error message.

Take into account that in order to apply this changes you should have to change the Prism source code or if you want to avoid this you could replace the existing Region Behavior with a new implementation which will be the same as the default one, but including the changes mentioned in the aforementioned work item, for more information on how to achieve this I recommend you to check the following section of the Prism documentation:

Regards,

Agustin Adami
http://blogs.southworks.net/aadami