Reputation: 129
how can I set a window as owner that is declared, initialised and opened from ViewModel?
Here is the code:
public class ViewModel : INotifyPropertyChanged
{
// declaration
static nextWindow nw;
...
public ICommand OpenNextWindow { get { return new RelayCommand(OpenNextWindowExecute, CanOpenNextWindowExecute); } }
bool CanOpenNextWindowExecute(object parameter)
{
return true;
}
void OpenNextWindowExecute(object parameter)
{
nw = new nextWindow();
nw.WindowStartupLocation = WindowStartupLocation.CenterScreen;
// Set this window as owner before showing it...
nw.Show();
}
}
In code-behind-file of nextWindow I can set nextWindow as owner with this code:
nw.Owner = this;
How can I realize it from the viewmodel ?
Upvotes: 3
Views: 5681
Reputation: 711
The whole idea behind MVVM is that you want a clean separation between your views and business logic, which enables better maintenance, scalability, testing etc. Your view model should thus ALMOST always be unaware of the existence of any view.
Thus make use of a messenger service which views or some view handler can listen to and then decide if it wants to process the message or not. Thus leaving the viewhandler to decide on which other view to call next or what message box to show.
There are numerous options available but as @Oyiwai said MVVMLight's Messenger service is quick an easy to use.
In your Package Manager Console run install-package MvvmLightLibs. MvvmLightLibs also has an added bonus in the fact that it already has an implementation of INotifyPropertyChanged which I saw you implemented.
Note this is a quick example. I don't recommend using the case statement as I did here which hardcodes he view names.
Create a WindowMessage class..
public class RaiseWindowMessage
{
public string WindowName { get; set; }
public bool ShowAsDialog { get; set; }
}
In your viewmodel
public class ViewModel : ViewModelBase
{
public RelayCommand<string> RaiseWindow => new RelayCommand<string>(raiseWindow, canRaiseWindow);
private bool canRaiseWindow(string nextWindowName)
{
// some logic
return true;
}
private void raiseWindow(string nextWindowName)
{
RaiseWindowMessage message = new RaiseWindowMessage();
message.WindowName = nextWindowName;
message.ShowAsDialog = true;
MessengerInstance.Send<RaiseWindowMessage>(message);
}
}
In your view or preferably in some view handler class..
public class ViewHandler
{
public ViewHandler()
{
Messenger.Default.Register<RaiseWindowMessage>(this, raiseNextWindow);
}
private void raiseNextWindow(RaiseWindowMessage obj)
{
// determine which window to raise and show it
switch (obj.WindowName)
{
case "NextWindow":
NextWindow view = new NextWindow();
if (obj.ShowAsDialog)
view.ShowDialog();
else
view.Show();
break;
// some other case here...
default:
break;
}
}
}
Upvotes: 2
Reputation: 471
To be honest I wouldn't do anything that's related with displaying windows in the ViewModel. What you can do though, is send a message (for example using MVVMLight's Messenger service) to the View, where you can do the show and set owner shinanigaz
Upvotes: 4