2013-08-18 148 views
1

我在一个视图模型第一种方法,即 :棱镜从区域

1)利用Prism删除视图模型注册我的ViewModels在一个容器(在这种情况下的统一)。

2)我为每个vm提供一个DataTemplate(UserControl)。

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

_regionManager.RequestNavigate(regionName, viewModelName, navigationCallBack); 

这工作得很好,但是当我试图从该区域中删除 “查看”,我得到以下异常:

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在“视图”集合中找到。任何想法什么是错的,以及如何解决这个问题?

+0

http://compositewpf.codeplex.com/discussions/396304 我的视图模型被打上IRegionMemberLifetime.KeepAlive 并返回假的,我不知道这是什么意思是棱镜删除视图时但因为我现在不需要它,所以我只是将它删除了。 –

回答

1

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

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

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

只是重申 -

  • 保持活动返回FALSE = region.Deactivate(图)
  • 保持活动返回true = region.Remove(图)
1

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

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); 
      } 
     } 
    }