Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I tell my DataTemplate to bind to a property in the PARENT ViewModel?

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> 
like image 984
Edward Tanguay Avatar asked Jun 22 '09 09:06

Edward Tanguay


People also ask

How to bind a property in XAML?

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.

How to bind property in WPF?

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.


1 Answers

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?.

like image 102
Edward Tanguay Avatar answered Oct 06 '22 23:10

Edward Tanguay