Я обычно справляюсь с этим, создавая своего рода WindowViewLoaderService.Когда ваша программа инициализируется, вы регистрируете свои Window и ваши ViewModel с кодом, подобным следующему:
WindowViewLoaderService.Register(TypeOf(MainWindowView), TypeOf(MainWindowViewModel));
WindowViewLoaderService.Register(TypeOf(MyWindowView), TypeOf(MyWindowViewModel));
Тогда, когда вы можете, например, позвонить в эту службу из вашей ViewModel, и все, на что вам нужно ссылаться, это ваша другая ViewModel.Например, если вы находитесь в вашей MainWindowViewModel, у вас может быть такой код:
var myChildWindowVM = new MyWindowViewModel();
WindowViewLoaderService.ShowWindow(myChildWindowVM);
Затем WindowViewLoaderService будет искать, какой View связан с указанной ViewModel, которую вы передали ему.Он создаст это представление, установит его DataContext равным ViewModel, который вы передали, а затем отобразит представление.
Таким образом ваши ViewModels никогда не узнают ни о каких представлениях.
Вы можете свернуть свой собственный.из этих услуг довольно легко.Все, что ему нужно сделать, это сохранить словарь, ключом которого будет ваш ViewModelType, а значением - ваш ViewType.Метод Register добавляет ваш словарь, а метод ShowWindow ищет правильное представление на основе переданной ViewModel, создает представление, устанавливает DataContext и затем вызывает Show для него.
Большинство фреймворков MVVM предоставляют что-то вродеэто для вас из коробки.Например, у Caliburn есть гладкий, который просто использует соглашение об именах, он называется ViewLocator в этой платформе.Вот ссылка, которая суммирует: http://devlicio.us/blogs/rob_eisenberg/archive/2010/07/04/mvvm-study-segue-introducing-caliburn-micro.aspx
Cinch, с другой стороны, называет его WPFUIVisualizerService, который вы можете увидеть в действии здесь: http://www.codeproject.com/KB/WPF/CinchIII.aspx
Это должно помочь вам начать работу.