The ViewModel to ViewModel communication is usually handled by an implementation of the Event Aggregator pattern.
MVVM Light uses the Messenger
class, Prism has another implementation but basically that is one way to send messages between View Models without coupling.
There are some examples, and Articles describing the usage.
I would suggest taking a look at it.
Regarding the controllers stuff in WPF, I don't know.
Regarding the example:
-I Have a Windows with its WindowsViewModel. This class should have a Command bound to the Button.
-The user clicks the button. Executes the command.
-The Command opens a new Window.
Here you should create the Dialog View Model and somehow you should create the Window. Or create the Window with a ViewModel, but ViewModel shouldn't know much about the View otherwise is not testable.
We use something like this because we have some requirements, but it
could be much much simplier, it happens it's the only example I have at hand:
bool? ShowDialogImpl<TViewModel>(Action<TViewModel> setup) where TViewModel : ViewModel
{
return (bool?)DispatcherHelper.UIDispatcher.Invoke(
(Func<bool?>)(() =>
{
var viewModel = viewModelFactory.Get<TViewModel>();
viewModel.ViewService = this;
setup(viewModel);
var window = new Window
{
Owner = this,
SizeToContent = SizeToContent.WidthAndHeight,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Content = ViewFactory.CreateView<TViewModel>(),
DataContext = viewModel,
WindowStyle = WindowStyle.ToolWindow,
ShowInTaskbar = false
};
window.SetBinding(TitleProperty, new Binding("Title"));
openDialogs.Push(window);
window.Activated += (sender, args) => window.SizeToContent = SizeToContent.Manual;
var result = window.ShowDialog();
openDialogs.Pop();
viewModelFactory.Release(viewModel);
return result;
}));
}
Basically: We create a window and with a view model.
The view model is created from a factory using an container.
The setup Action delegate is the entry point for our data.
The first Windows is a Grid, and the second Dialog to edit data of the grid.
Inf the Windows we have:
messenger.Register<EntityUpdated<FooClass>>(this, message => UpdateItem(message.Entity));
And in the Dialog:
messenger.Send(new EntityUpdated<FooClass>(subject));
This way, we know when something was updated in the Edit Dialog in order to refresh the grid.
Hope this help you :)