I've got the following MainView.xaml file that works well as a MVVM menu switcher. I've got these pairs:
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>
One-Way Data Binding The following XAML code creates four text blocks with some properties. Text properties of two text blocks are set to “Name” and “Title” statically, while the other two text blocks Text properties are bound to “Name” and “Title” which are class variables of Employee class which is shown below.
Data binding is a mechanism in WPF applications that provides a simple and easy way for Windows Runtime apps to display and interact with data. In this mechanism, the management of data is entirely separated from the way data. Data binding allows the flow of data between UI elements and data object on user interface.
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?.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With