2013-08-18 185 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); 
      } 
     } 
    }