34

I've got the following MainView.xaml file that works well as a MVVM menu switcher. I've got these pairs:

  • Page1View / Page1ViewModel
  • Page2View / Page2ViewModel

in my MainViewModel I fill an ObservableCollection with both ViewModels, then when the user clicks the Next button, it calls NextPageCommand in MainViewModel which switches out CurrentPageViewModel with a new ViewModel which is then displayed with an appropriate View, works nicely.

I also have a Menu being filled with all the titles from the ViewModels in the Observable collection, which also works nicely.

However, each MenuItem has a Command="{Binding SwitchPageCommand}" which SHOULD call SwitchPageCommand on the MainViewModel and not on e.g. Page1ViewModel or Page2ViewModel.

So how can I indicate in the template not to bind to the current ViewModel but the ViewModel which contains that ViewModel, e.g. something like this:

PSEUDO-CODE: <DataTemplate x:Key="CodeGenerationMenuTemplate"> <MenuItem Command="{Binding <parentViewModel>.SwitchPageCommand}" Header="{Binding Title}" CommandParameter="{Binding Title}"/> </DataTemplate> 

Here is MainViewModel:

<Window x:Class="TestMenu234.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestMenu234.Commands" xmlns:vm="clr-namespace:TestMenu234.ViewModels" xmlns:v="clr-namespace:TestMenu234.Views" Title="Main Window" Height="400" Width="800"> <Window.Resources> <DataTemplate x:Key="CodeGenerationMenuTemplate"> <MenuItem Header="{Binding Title}" Command="{Binding SwitchPageCommand}" CommandParameter="{Binding Title}"/> </DataTemplate> <DataTemplate DataType="{x:Type vm:Page1ViewModel}"> <v:Page1View/> </DataTemplate> <DataTemplate DataType="{x:Type vm:Page2ViewModel}"> <v:Page2View/> </DataTemplate> </Window.Resources> <DockPanel> <Menu DockPanel.Dock="Top"> <MenuItem Header="Code _Generation" ItemsSource="{Binding AllPageViewModels}" ItemTemplate="{StaticResource CodeGenerationMenuTemplate}"/> </Menu> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> <Button Margin="5" Content="Next Page" Command="{Binding NextPageCommand}"/> </StackPanel> <ContentControl Content="{Binding CurrentPageViewModel}"/> </DockPanel> </Window> 

1 Answer 1

58

The answer is this:

<DataTemplate x:Key="CodeGenerationMenuTemplate"> <MenuItem Header="{Binding Title}" Command="{Binding DataContext.SwitchPageCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}" CommandParameter="{Binding Title}"/> </DataTemplate> 

I just saw that Nir had given me the syntax to solve the above issue on this question: What is the best way in MVVM to build a menu that displays various pages?.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.