Сервис создания модальных и немодальных окон в контексте паттерна MVVM
Как в контексте паттерна MVVM правильно и красиво реализовать сервис создания модальных и немодальных окон. Хотелось бы что-то вроде: myWindowSrv.ShowWindow(myChildViewModel);
Т.е. мы вызываем сервис создания окон, передаем ему нужную ViewModel и сервис на основе типа этой ViewModel отображает нужную View
Ответ
В качестве базы вы можете сделать так: class DisplayRootRegistry
{
Dictionary vmToWindowMapping = new Dictionary(); public void RegisterWindowType() where Win: Window, new() where VM : class
{
var vmType = typeof(VM);
if (vmType.IsInterface)
throw new ArgumentException("Cannot register interfaces");
if (vmToWindowMapping.ContainsKey(vmType))
throw new InvalidOperationException(
$"Type {vmType.FullName} is already registered");
vmToWindowMapping[vmType] = typeof(Win);
} public void UnregisterWindowType()
{
var vmType = typeof(VM);
if (vmType.IsInterface)
throw new ArgumentException("Cannot register interfaces");
if (!vmToWindowMapping.ContainsKey(vmType))
throw new InvalidOperationException(
$"Type {vmType.FullName} is not registered");
vmToWindowMapping.Remove(vmType);
} public Window CreateWindowInstanceWithVM(object vm)
{
if (vm == null)
throw new ArgumentNullException("vm");
Type windowType = null; var vmType = vm.GetType();
while (vmType != null && !vmToWindowMapping.TryGetValue(vmType, out windowType))
vmType = vmType.BaseType; if (windowType == null)
throw new ArgumentException(
$"No registered window type for argument type {vm.GetType().FullName}"); var window = (Window)Activator.CreateInstance(windowType);
window.DataContext = vm;
return window;
}
}
Имея это, можно накручивать сверху разную логику открытия/закрытия. Например, вы можете писать команды открытия/закрытия вручную: class DisplayRootRegistry
{
// начало см. выше Dictionary
Комментариев нет:
Отправить комментарий