Призма - условная навигация
-
05-07-2019 - |
Вопрос
Я использую Prism для навигации в своем Wpf-приложении. У меня есть несколько модулей, и каждый из них регистрирует себя в главном меню с помощью общих команд, отправляемых с использованием контейнера IoC в загрузчике. Пункты меню связаны с общими командами для навигации - что откроет правильный вид в некотором регионе. Все основано на рекомендациях, которые я нашел на сайте Prism. Р>
Моя проблема сейчас в том, что у меня есть модуль, в котором есть условие, указывающее, хочу ли я открыть ViewA или ViewB в основной области. Пример. Допустим, у меня есть модуль клиента, а затем - «Клиент». пункт меню, который откроет клиентский модуль на главном экране. И есть условие: если у меня есть активный клиент, я хочу открыть CustomerDetailsView при нажатии на пункт меню, иначе я хочу открыть CustomersAdminView.
Каков рекомендуемый подход к решению этой проблемы? Я вижу несколько вариантов, но я думаю, что все они звучат немного странно. Сейчас я работаю над созданием того, что будет MasterCustomerView в примере выше. Это представление затем проверит условие и откроет UserControl, предоставив внутри детали Подробности администрирования. Я не все удовлетворены этим решением, хотя - это будет законный подход? Лучше? Р>
Решение
В системах меню, построенных на основе Prism, я предусмотрел перегрузку для модулей, регистрирующих представления, которая позволяет им передавать делегат, а не тип представления. В этом делегате я могу передать соответствующую информацию делегату, чтобы он мог решить, как создать свое представление.
Это немного сложно, но я могу привести несколько примеров.
public interface IMenuRegistry
{
void RegisterMenuItem(string title,
Func<RelevantInformation, Object> executeFunction,
Func<RelevantInformation, bool> canExecuteFunction);
void RegisterMenuItem(string title, Type viewType);
}
Обратите внимание, у меня есть тип, который передается в " RelevantInformation " который может содержать текущего клиента и т. д. Когда пользователь нажимает на элемент меню, я вызываю делегата и передаю всю информацию, которая может понадобиться для принятия решения. Он возвращает объект View, который я могу затем поместить в любой подходящий регион.
Я также разрешаю модулю передавать " canExecute " делегат, аналогично тому, как работает команда (на самом деле, я беру все регистрации в меню и превращаю их в команды). Таким образом, модуль также может отключить себя, если какое-либо условие в RelevantInformation сделает пункт меню недействительным.
На самом деле это только один из многих способов решения этой проблемы, но это близко к тому, что я делаю. Надеюсь, вы найдете это полезным или заставите задуматься об альтернативных способах решения проблемы.