0

I am not totally new to MVVM or WPF but I have this problem where I want to switch from one window to another in WPF using the MVVM pattern. I can get it to work when switching between UserControls, but not Windows. I have looked at the following:

WPF MVVM Switching Between Usercontrols

WPF MVVM navigate views

It seems that it almost works, but it goes into break mode after switching window instead of displaying the window.

So what I got so far is:
- Two windows (WPF)
- A base view model implementing INotifyPropertyChanged and two view models inheriting from it.

The code below is simply from a simple project I made in order to try to make this work.

I have made the following Datatemplates in the App.xaml as suggested above:

<Application.Resources>
    <DataTemplate DataType="{x:Type local:MainWindowVM}">
        <local:MainWindow/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:SignUpVM}">
        <local:SignUpWindow/>
    </DataTemplate>              
</Application.Resources>

My MainWindowVM got a command used to instantiate the new view model in order to change view:

    private BaseVM _viewModel;

    public BaseVM ViewModel {
        get => _viewModel;
        set {
            _viewModel = value;
            OnPropertyChanged();
        }
    }
    public ICommand SignUpCmd { get; set; }
    public MainWindowVM()
    {
        SignUpCmd = new SignUpCommand(this);
    }

    public void Execute()
    {
        ViewModel = new SignUpVM();
    }

The corresponding xaml code for the MainWindow:

<Grid>        
    <ContentControl Content="{Binding ViewModel, UpdateSourceTrigger=PropertyChanged}"/>
    <Button Content="Sign Up" Width="100" Height="100" Command="{Binding SignUpCmd}"/>
</Grid> 

Then for the SignUpWindow the view model and view is simply empty.

So I tried debugging and I can see that it do change view and initializes the SignUpWindow by calling the InitializeComponent method in the constructor:

public SignUpWindow()
    {
        InitializeComponent();
    }

But after that it goes into breakmode with the following error:

System.Windows.Markup.XamlParseException: Window must be the root of the tree. Cannot add Window as a child of Visual

So my initial thoughts on why this does not work is that I can not use the
local:MainWindow and local:SignUpWindow in the App.xaml,
simply because they are Windows.

I do not know if this is the proper way of switching between windows and I would really appreciate if someone can spot the error or give an alternative, thanks :)

Bizhan
  • 16,157
  • 9
  • 63
  • 101
Jacob G.
  • 21
  • 5
  • The message says you can't add a Window to a Window. so why don't you use UserControls instead of Windows? – Bizhan Aug 05 '18 at 13:18
  • I could use UserControls instead, but it is simply just to know how to switch between Windows for future purposes. – Jacob G. Aug 05 '18 at 16:33
  • A window is the container of controls so switching between windows does not make sense when you can switch between controls. You should have one window with several controls. – Bizhan Aug 05 '18 at 16:37
  • Ohh I see, so I would likely not end up in a situation where I would need to switch between Windows assuming the application is well designed, correct? – Jacob G. Aug 05 '18 at 18:52
  • Exactly. You most likely need one window for the whole app and a few more for e.g. tools etc – Bizhan Aug 05 '18 at 18:55
  • Great to know and thanks. Now one last question out of curiosity, if I needed to switch between two Windows, would it be possible using the MVVM design pattern or is it one of its weaknesses? – Jacob G. Aug 05 '18 at 20:49
  • If you want to switch between windows, you have to instantiate them "manually" like `mainWin = New MainWindow;` and `mainWin .Show();`. And you can even bind them to events in your VM to show them properly without breaking the *MVVM* model. – P.Manthe Aug 06 '18 at 01:24
  • Thank you. I will look that up if I need it. For now, I am just going to use UserControls. – Jacob G. Aug 06 '18 at 09:27

0 Answers0