Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
So here is my question: What is the best way to achieve the navigation between UserControl contained in a MainWindows, assuming that:

I've a ViewModel for each UserControl and one for the Main Windows.
The buttons for switching between usercontrols are contained into UserControl itself
- I've a ViewModelLocator
- I need to sometimes Destroy/re-create a userControl's ViewModel
- I want to respect the MVVM Pattern.
- I want to keep it simple
example : Having a mainwindow.xaml which contain the content control and 3 user control in my view lets say FirstView, SecondView, ThirdView. Firstview contain button and on click that button navigate to SecondView and SecontView contain button and on click navigate to ThirdView, And Third view Contain button that will navigate to FirstView.

What I have tried:

I tried with datatemplate, but if button on main window, But in my case button is on usercontrol itself.
Posted
Updated 29-Nov-19 17:37pm
v2

1 solution

you can first try to make all three User controls as separate views and viewmodel
MainView.xmal -> MainViewModel
FirstView.xmal -> FirstViewModel
SecondView.xmal -> SecondViewModel
ThridView.xmal -> thirdViewModel

MainviewModel have
RelayCommand MainButtonClickEventHandler
for Mainview Button and bind with
Command="{Binding Path=MainButtonClickEventHandler}"


On execute of this command
var FirstV = new FirstView() { datacontext = FirstViewModel };
FirstView.Show();
// or Close MainView() if it required.

repeat same concept for second and third view and view model.
 
Share this answer
 
Comments
Member 11859517 2-Dec-19 0:01am    
Thanks Ashutosh,

I have 3 user control with ViewModel,
but var FirstV = new FirstView(){DataContext = FirstViewModel}
is giving error that 'FirstViewModel' is a type which is not valid for given context,

but i guess this solution for if button on mainView, But my button on usercontrol, on that button click want to open on another user control on,
i m new to mvvm, Pls if u provide code block. it wolud help me
[no name] 2-Dec-19 1:14am    
you are very close to your solution, i can give you few hints and tips and code to start with..later you can improve it using your thoughts.
i have created mainwindow type of window and firstuser control type of user control.
one viewModel for FirstVM.

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
var firstv = new firstview() { DataContext = new FirstVM() };

var window = CreateWindow();
window.Content = firstv;
this.Hide();

window.Owner.OwnedWindows[0].ShowDialog(); // ask owner of this window to show dialog.
}

private Window CreateWindow()
{
return new Window
{
WindowStyle = WindowStyle.None,
SizeToContent = SizeToContent.WidthAndHeight,
AllowsTransparency = true,
ShowInTaskbar = true,
Owner = this,
WindowStartupLocation = WindowStartupLocation.CenterScreen
};
}
}

public class FirstVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}
[no name] 2-Dec-19 1:15am    
you can improve your window part in this code, like style and location etc etc.
Member 11859517 2-Dec-19 1:54am    
thanks, I am using MVVM light. Here why I want to use code in code behind of main window,
what extactly i have to do is,
I my main window i have
<contentcontrol margin="10" grid.row="1" name="viewLoader" content="{Binding CurrentViewModel}">

In my mainViewModel i have property of type ViewModelBase
private ViewModelBase currentViewModel;
public ViewModelBase CurrentViewModel
{
get { return currentViewModel; }
set
{
currentViewModel = value;
RaisePropertyChanged(() => CurrentViewModel);
}
}
how to set this property from my FirstviewModel, i mean i want to assign FirstView to Content control
using mvvm
[no name] 2-Dec-19 3:38am    
1. first make IviewModelbase to implement all three viewmodels with the same.
2.
public interface IViewModelBase { }
public class MainViewModel : INotifyPropertyChanged
{
private IViewModelBase currentViewModel;

public IViewModelBase CurrentViewModel
{
get { return currentViewModel; }
set
{
currentViewModel = value;
RaisePropertyChanged(nameof(CurrentViewModel));
}
}

public event PropertyChangedEventHandler PropertyChanged;

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

internal void OpenFirstControl()
{
CurrentViewModel = new FirstVM();
RaisePropertyChanged(nameof(CurrentViewModel));
}
}

FirstVM.cs
public class FirstVM : INotifyPropertyChanged, IViewModelBase
{
public event PropertyChangedEventHandler PropertyChanged;
}

MainView.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
var mainViewModel = this.DataContext as MainViewModel;
mainViewModel.OpenFirstControl();
var firstv = new firstview() { DataContext = mainViewModel.CurrentViewModel };

var window = CreateWindow(this);
window.Content = firstv;
this.Hide();

window.Owner.OwnedWindows[0].ShowDialog();
}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900