ACmiester
ACmiester

Reputation: 1

Set frame content when a button is clicked using MVVM

I'm new to the MVVM pattern, but I understand some of it. The problem I currently have is that I want to open a page when a button is pressed, using the MVVM pattern. When one of the six buttons is pressed, a command can give me the name of the button that is pressed. My problem is that I don't know how to set the frame's content when the button is pressed.

    <StackPanel>
        <Button Content="Page 1" x:Name="Page1"
                Command="{Binding SimpleCommand, Source={StaticResource ViewModelBase}}" 
                CommandParameter="{Binding Name, ElementName=Page1}"/>
        <Button Content="Page 2" x:Name="Page2"
                Command="{Binding SimpleCommand, Source={StaticResource ViewModelBase}}" 
                CommandParameter="{Binding Name, ElementName=Page2}"/>
    </StackPanel>

Above is the XAML code right now. The simplecommand is just to write out the name on the button

 <Frame x:Name="MainFrame" Grid.Column="1" Grid.Row="1"
           Content="{Binding Name, Converter={StaticResource Converter}, ElementName=Page1}" 
           NavigationUIVisibility="Hidden"/>

Above is the Frame that i want to change the content. On compile time i can set the page that it should open. I want to set the content on run time, where i use the button name. The converter is just the IValueConverter, where i set what page it should display.

Upvotes: 0

Views: 825

Answers (1)

XAMlMAX
XAMlMAX

Reputation: 2363

The way I have approached this was not by using a frame but using a ContentPresenter. You can always insert the ContentPresenter inside of your Frame. Bear in mind that Frame doesn't inherit DataContext so I would avoid using it.
To start of let's create a BaseViewModel be our starting point for views.

public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}  

Now that we have the base let's create a MainViewModel:

public class MainViewModel : BaseViewModel
{
    private BaseViewModel selectedViewModle;

    public BaseViewModel SelectedViewModel
    {
        get { return selectedViewModle; }
        set { selectedViewModle = value; OnPropertyChanged(nameof(SelectedViewModel)); }
    }
}  

At this point our MainViewModel has a property with SelectedViewModel this is what we are going to use for our navigation.
Assumption
I am assuming that you have a working knowledge about commands and how to use them.
Here is a code example of a method for your Navigate command:

void navigate(object parameter)
{
    SelectedViewModel = new DetailsViewModel();
}  

And here is the code for DetailsViewModel:

public class DetailsViewModel : BaseViewModel
{
    //your code with properties and methods here
}  


Now let's set up the view:

<UserControl ...>
    <Grid>
        <ContentPresenter Content="{Binding .}"/>
    </Grid>
</UserControl>  

Now in the Resources tag for your UserControl include a DataTemplate:

<DataTemplate DataType="{x:Type vm:DetailsViewModel}">
    <Grid .../>
</DataTemplate>  

At this point you will have the content of the data template presented for you on the screen.

Upvotes: 1

Related Questions