I'm trying to build my first app with WPF and in order to fully understand MVVM I'm not using any framework, the only helper I use is Microsoft.Toolkit.Mvvm I have thi app with 2 pages, one is the master and the other one is the detail. I did set up navigation as it's explained in WPF MVVM navigate views Now I don't understand how I should tell to the detail screen which data it should display, since I'm not allowed to pass parameters to the viewmodel that I am instantiating in the datacontext.
My MainWindow.xaml
<Window x:Class="AlgsManagerDesktop.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AlgsManagerDesktop"
xmlns:views="clr-namespace:AlgsManagerDesktop.Views"
xmlns:viewModel="clr-namespace:AlgsManagerDesktop.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type viewModel:MasterViewModel}">
<views:MasterView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:DetailsViewModel}">
<views:DetailsView />
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<viewModel:MainWindowViewModel />
</Window.DataContext>
<Grid>
<ContentControl Content="{Binding ViewModel}" />
</Grid>
</Window>
MainWindowViewModel.cs
public class MainWindowViewModel : ObservableObject
{
private BaseViewModel viewModel;
public BaseViewModel ViewModel
{
get => viewModel;
set => SetProperty(ref viewModel, value);
}
public RelayCommand SwitchToDetailsCommand { get; }
public MainWindowViewModel()
{
ViewModel = new MasterViewModel();
SwitchToDetailsCommand = new RelayCommand(SwitchToDetails);
}
private void SwitchToDetails()
{
ViewModel = new DetailsViewModel();
}
}
MasterViewModel.cs
public class MasterViewModel : BaseViewModel
{
private ItemModel selectedItem;
public ItemModel SelectedItem
{
get => selectedItem;
set
{
SetProperty(ref selectedItem, value);
DeleteCommand.NotifyCanExecuteChanged();
}
}
public ObservableCollection<ItemModel> items { get; set; }
public RelayCommand DeleteCommand { get; }
public MasterViewModel()
{
DeleteCommand = new RelayCommand(RemoveItem, ItemIsSelected);
}
private void RemoveItems()
{
AlgSets.Remove(SelectedItem);
}
private bool ItemIsSelected()
{
return SelectedItem != null;
}
}
MasterView.xaml
<UserControl x:Class="AlgsManagerDesktop.Views.MasterView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AlgsManagerDesktop.Views"
xmlns:viewModel="clr-namespace:AlgsManagerDesktop.ViewModel"
xmlns:root="clr-namespace:AlgsManagerDesktop"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<viewModel:MasterViewModel/>
</UserControl.DataContext>
<!-- ListBox here that updates a SelectedItem property -->
<!-- this button handles navigation to details screen, I'd like to pass SelectedItem to the next screen -->
<Button Command="{Binding DataContext.SwitchToDetailsCommand,
RelativeSource={RelativeSource AncestorType={x:Type root:MainWindow}},
Mode=OneWay}">
Open Selected
</Button>
</UserControl>
DetailsView.xaml
<UserControl x:Class="AlgsManagerDesktop.Views.DetailsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AlgsManagerDesktop.Views"
xmlns:viewModel="clr-namespace:AlgsManagerDesktop.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<viewModel:DetailsViewModel/>
</UserControl.DataContext>
<-- Item details here, I'd like to take them from an Item property in the DetailsViewModel -->
</UserControl>