How can I tell my DataTemplate to bind to a property in the PARENT ViewModel?
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?.
Angry Dan
web/software developer, .NET, C#, WPF, PHP, software trainer, English teacher, have philosophy degree, love languages, run marathons my tweets: http://www.twitter.com/edward_tanguay my runs: http://www.tanguay.info/run my code: http://www.tanguay.info/web my publications: PHP 5.3 training video (8 hours, video2brain) my projects: http://www.tanguay.info
Updated on September 11, 2020Comments
-
Angry Dan over 3 years
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>