user10946936
user10946936

Reputation: 1

WPF MVVM Navigate between Views on button click

I am trying to create a WPF application and for Navigation I am using the example I found at

https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/

Now, I need to navigate from one UserControl to another on button click.

Can somebody guide me how to achieve this with MVVM? Or if I should look at using some framework for Navigation.

Upvotes: 0

Views: 1136

Answers (1)

Chris Mack
Chris Mack

Reputation: 5208

This will depend somewhat on context, but many times I use a technique where I have an object (or some kind of abstract class) with a name like "MainContent" inside of some ViewModel. This is responsible for holding content to be displayed in a ContentControl.

My XAML would look something like this, where Type1View and Type2View would be UserControls (vw_Type1 and vw_Type2 are references to their namespaces), and then I would navigate between them by setting MainContent to an instance of either Type1ViewModel or Type2ViewModel.

<ContentControl Content="{Binding MainContent}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type vm_Type1:Type1ViewModel}">
            <vw_Type1:Type1View />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm_Type2:Type2ViewModel}">
            <vw_Type2:Type2View />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

This would be taken care of perhaps with a button (or two buttons in the below example) outside of the ContentControl, that sends a command to the ViewModel containing MainContent, which simply changes the MainContent property, either to an existing or new instance of Type1ViewModel or Type2ViewModel. E.g.:

private Type1ViewModel _type1ViewModel;
public Type1ViewModel Type1ViewModel
{
    get { return _type1ViewModel; }
    set
    {
        if (_type1ViewModel != value)
        {
            _type1ViewModel = value;
            NotifyPropertyChanged();
        }
    }
}

private Type2ViewModel _type2ViewModel;
public Type2ViewModel Type2ViewModel
{
    get { return _type2ViewModel; }
    set
    {
        if (_type2ViewModel != value)
        {
            _type2ViewModel = value;
            NotifyPropertyChanged();
        }
    }
}

...

private ObservableObject _mainContent;
public ObservableObject MainContent
{
    get { return _mainContent; }
    set
    {
        if (_mainContent != value)
        {
            _mainContent = value;
            NotifyPropertyChanged();
        }
    }
}

...

public InternalDelegateCommand NavigateToType1Command => new InternalDelegateCommand(NavigateToType1);
public InternalDelegateCommand NavigateToType2Command => new InternalDelegateCommand(NavigateToType2);

...

private void NavigateToType1() => MainContent = Type1ViewModel;
private void NavigateToType2() => MainContent = Type2ViewModel;

So to complete the XAML for this example:

<Button Content="Type 1" Command="{Binding NavigateToType1Command}" />
<Button Content="Type 2" Command="{Binding NavigateToType2Command}" />
<ContentControl Content="{Binding MainContent}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type vm_Type1:Type1ViewModel}">
            <vw_Type1:Type1View />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm_Type2:Type2ViewModel}">
            <vw_Type2:Type2View />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

(For information on InternalDelegateCommand, see my answer to this question.)

Upvotes: 1

Related Questions