2013-08-18 3 views
1

я использую Prism в первом подходе ViewModel, т.е .:Призма удалить ViewModel из области

1) зарегистрировать свои ViewModels в контейнере (единство в данном случае).

2) Я поставляю DataTemplate (UserControl) для каждого vm.

3) Я перемещаюсь с использованием имени 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». Любая идея, что не так и как обойти это?

+0

http://compositewpf.codeplex.com/discussions/396304 Мой ViewModel был отмечен IRegionMemberLifetime.KeepAlive и возвращается ложь, я не знаю, что это значит для Prism при удалении зрения но поскольку я не нуждался в этом, я просто удалил его. –

ответ

1

Если 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 возвращение Ложные = region.Deactivate (вид)
  • KeepAlive возвращение Правда = region.Remove (вид)
1

Благодаря ответ TrialAndError в , Я обнаружил деактивирующие элементы, если KeepAlive ошибочно решил мои проблемы, однако все наши классы были настроены с использованием атрибута 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); 
      } 
     } 
    }