Prism从区域中删除ViewModel

时间:2013-08-18 15:11:15

标签: wpf prism viewmodel region

我在ViewModel的第一种方法中使用Prism, 即:

1)我在一个容器中注册了我的ViewModel(在这种情况下是统一的)。

2)我为每个虚拟机提供DataTemplate(UserControl)。

3)我使用我在Container注册的ViewModel名称进行导航。

    _regionManager.RequestNavigate(regionName, viewModelName, navigationCallBack);  

这很好用,但是当我尝试从这个区域删除“View”时,我得到以下异常:

 The region does not contain the specified view. Parameter name: view

我尝试删除:

  var region = _regionManager.Regions[requests[i].RegionName];                                     
  var view = region.Views.Single(v => v.GetType().Name == requests[i].ViewName);
  region.Remove(view);   

ViewModel位于“Views”集合中。知道什么是错的,以及如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

如果IRegionMemberLifetime.KeepAlive返回false,则每次导航到视图时都会创建一个新视图。如果返回True,则保持该视图处于活动状态,并在导航到时返回相同的视图。

在使用KeepAlive返回false时无法删除视图的原因是,从技术上讲,在您调用删除视图时,视图已被删除。您需要停用视图,而不是将其删除。不用担心,由于KeepAlive返回false,视图将从集合中移除并处理掉,您只是真的告诉用户界面将其停用。

var region = _regionManager.Regions[requests[i].RegionName];                                     
var view = region.Views.Single(v => v.GetType().Name == requests[i].ViewName);
region.Deactivate(view);   

重申 -

  • KeepAlive返回False = region.Deactivate(view)
  • KeepAlive返回True = region.Remove(view)

答案 1 :(得分:2)

感谢TrialAndError的回答,如果KeepAlive为false,我发现停用项目解决了我的问题,但是我们所有的类都设置了KeepAlive属性而不是实现IRegionMemberLifetime接口,这使得检查KeepAlive有点棘手。我想出了这个循环,我们用它来卸载一个区域的所有视图。我希望这可以帮助别人。这适用于IRegionMemberLifetime接口和RegionLifetimeAttribue,其中KeepAlive设置为false。

 public static void RemoveAllViews(this IRegion region)
    {
        /*
          * If KeepAlive == false we must deactiveate rather than trying to remove it.
          * KeepAlive can be set by implementing IRegionMemberLifetime interface, or by setting the KeepAlive attribute, 
          * so we must check both. 
          * Use reflection to determine if the view has a KeepAlive attribute, and if it does, then is KeepAlive == false. 
          * 
         * */ 
        foreach (object view in region.Views)
        {
            Type type = view.GetType();
            if (null != Attribute.GetCustomAttribute(type, typeof(RegionMemberLifetimeAttribute)))
            {
                RegionMemberLifetimeAttribute attribute = (RegionMemberLifetimeAttribute)Attribute.GetCustomAttribute(type, typeof(RegionMemberLifetimeAttribute));
                if (attribute.KeepAlive == false)
                    region.Deactivate(view);
            }
            else if (view is IRegionMemberLifetime && !((IRegionMemberLifetime)view).KeepAlive)
            {
                region.Deactivate(view);
            } 
            else //This is not an item that has KeepAlive set to false so remove it
            {
                region.Remove(view); 
            } 
        }
    }