Перейдите к определенному представлению в области нескольких представлений
Я работаю над приложением WPF, которое использует платформу Microsoft Prism. Одним из аспектов приложения является "модальная" область, которая может содержать любое количество модальных окон, которые накладываются на все окно. При перемещении большего количества видов в область каждое окно сдвигается вправо, чтобы новое окно занимало центр экрана. Вот более наглядное объяснение:
Когда "модальная" область содержит один вид:
Когда в область добавляется другой вид:
Когда добавлено еще несколько просмотров:
У меня это работает, используя пользовательский элемент управления, который управляет анимацией и отображением его дочерних элементов. Вот то, что пользовательский элемент управления RegionAdapter
"s Adapt
Метод выглядит так:
protected override void Adapt(IRegion region, ModalContainer regionTarget)
{
region.ActiveViews.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler((o, e) =>
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
foreach(FrameworkElement element in e.NewItems)
{
regionTarget.AddChild(element);
}
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
foreach (FrameworkElement element in e.OldItems)
{
regionTarget.RemoveChild(element);
}
}
});
}
Мой вопрос таков: как лучше вернуться к предыдущему окну? Прямо сейчас, единственный способ, которым я знаю, чтобы вызвать RemoveChild
вышеприведенный метод состоит в том, чтобы явно удалить представление из региона, для чего необходимо, чтобы я где-то хранил список всех представлений, находящихся в данный момент в регионе:
// to remove the most recently added view from the region
_regionManager.Regions["ModalRegion"].Remove(addedViews.Pop());
В идеале я мог бы перемещаться назад, используя концепцию журналирования Prism, но я не вижу пути в своем RegionAdapter
чтобы ответить, когда представление, уже находящееся в регионе, будет перемещено к.
Любые советы будут высоко оценены.
РЕДАКТИРОВАТЬ
Я смог достичь этой функциональности, следуя совету Г.О. Островского (см. Комментарии в принятом ответе) - я изменил свой адаптер региона, чтобы поддерживать только один активный вид в регионе (вид, который в настоящее время находится в центре экрана). Затем я могу настроить этот вид для удаления через myRegion.ActiveViews.FirstOrDefault()
,
ЕЩЕ ДРУГОЕ РЕДАКТИРОВАНИЕ
С тех пор я снова изменил эту реализацию, так как нам нужна была возможность удалить любое из представлений в регионе, а не только последнее. Смотрите принятый ответ для деталей.
2 ответа
Первоначально я решил эту проблему, позволив активировать только один регион, что гарантировало, что удаление текущего активного вида региона всегда удаляло вид, находящийся в настоящее время в центре экрана. Однако с тех пор нам нужна была возможность удалить любое из представлений региона, а не только первое. Для этого я понял, что Region.Views
собственность может быть приведена к List
и затем доступ по индексу:
List<object> allViews = modalRegion.Views.ToList<object>();
Мне немного неудобно с этим решением, так как IViewsCollection
определение наследуется от IEnumerable
не IList
; технически я мог бы передать обычай IViewsCollection
это не может быть приведено к IList
.... но в краткосрочной перспективе я собираюсь бежать с этим.
Если вы иногда хотите перейти обратно к предыдущему представлению, вы не должны удалять его из региона при переходе из него.
Вместо этого вы можете просто отключить его с помощью метода OnNavigatedFrom(). А затем используйте NavigationJournal, чтобы вернуться назад.
Что касается вашего элемента управления RegionAdapter, вы можете изменить его, чтобы он мог обрабатывать активацию и деактивацию View. Например, вы можете опубликовать событие De/ActivationChanged из каждого ViewModel OnNavigatedFrom() и OnNavigatedTo() и обработать эти события в своем пользовательском элементе управления, подписавшись на него и выполнив соответствующую задачу для каждого события.
Вы можете найти дополнительную информацию о навигации и агрегации событий в следующих главах MSDN Prism Guide:
Я надеюсь, что это помогает, С уважением.