Ответ зависит от того, владеет ли главное окно дочерними окнами как составное представление, или оно создает новые представления на лету (для модальных или немодальных дочерних окон).
В первом случае основной ViewModel должен напрямую владеть дочерними ViewModels, что означает, что вы можете реализовать дочерние ViewModels как свойства только для чтения в основной ViewModel и использовать привязку данных для привязки дочерних представлений к соответствующим свойствам.
Если вы хотите, чтобы основной ViewModel управлял созданием дочерних элементов напрямую или их впрыскивали в него с помощью Конструкторское внедрение , зависит от необходимой степени изменчивости.
Как всегда, если вам нужно создавать новые экземпляры дочерних представлений в произвольные моменты времени, лучше внедрить Абстрактная фабрика .
В качестве примера, я часто определяю и внедряю этот интерфейс в те из моих ViewModels, которые в нем нуждаются:
public interface IWindow
{
void Close();
IWindow CreateChild(object viewModel);
void Show();
bool? ShowDialog();
}
Это позволяет ViewModel создавать новые окна и показывать их (например, в виде диалогов). Простая реализация выглядит так:
public class WindowAdapter : IWindow
{
private readonly Window window;
public WindowAdapter(Window window)
{
if (window == null)
{
throw new ArgumentNullException("window");
}
this.window = window;
}
#region IWindow Members
public void Close()
{
this.window.Close();
}
public IWindow CreateChild(object viewModel)
{
var cw = new ContentWindow();
cw.Owner = this.window;
cw.WindowStartupLocation = WindowStartupLocation.CenterOwner;
cw.DataContext = viewModel;
return cw;
}
public void Show()
{
this.window.Show();
}
public bool? ShowDialog()
{
return this.window.ShowDialog();
}
#endregion
}