Search code examples
c#wpfmvvmdata-bindingdatacontext

Bindings from Multiple ViewModels in same View WPF MVVM


I have a WPF MVVM project that includes a View which contains several controls.

There is a DockPanel which contains all the controls in the View with DataContext to a MainViewModel Class, and inside of it there is a Grid with DataContext to other object ViewModel which it's property contained in the MainViewModel Class.

Now, in that Grid I have a 2 buttons surrounds with WrapPanel, and the buttons have a Commands to a property which wrote in the MainViewModel Class, and when I pressed on it nothing happens (Because the Grid's DataContext is to other object).

I need the Commands to be stay in the MainViewModel Class, How can I do that?

XAML: (just the relevant parts)

<DockPanel x:Name="MonitorParent" DataContext="{Binding MonitorMainViewModel}" LastChildFill="False" Width="1144" HorizontalAlignment="Left">
      .......     
    <StackPanel>
        <ContentControl Visibility="{Binding Path=NoMonitorsMessageVisibility, Converter={StaticResource visibilityConverter}}">
            <StackPanel Width="804" Height="574">
                <Grid DataContext="{Binding CurrentMonitor}" Margin="10 0" Height="auto">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" MinHeight="23" />
                        <RowDefinition Height="Auto" MinHeight="23" />
                        <RowDefinition Height="Auto" MinHeight="23" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="140" />
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Grid.Row="15"  Content="Serial Number" x:Name="SerialNumber"   />
                    <WrapPanel  DataContext="{Binding MonitorMainViewModel}" HorizontalAlignment="Center" Margin="0,10,0,10" Grid.ColumnSpan="2" Grid.Row="6" >
                        <Button Content="Add" Width="60" Margin="0,0,40,0" Command="{Binding AddConfidenceCommand}" />
                        <Button Content="Delete" Width="60" Margin="30,0,0,0" Command="{Binding DeleteConfidenceCommand}"/>
                    </WrapPanel>

                     ........
  </DockPanel

Solution

  • You could use the name of the DockPanel for binding like this:

    <DockPanel x:Name="MonitorParent" DataContext="{Binding MonitorMainViewModel}" LastChildFill="False" Width="1144" HorizontalAlignment="Left">
      .......     
    <StackPanel>
        <ContentControl Visibility="{Binding Path=NoMonitorsMessageVisibility, Converter={StaticResource visibilityConverter}}">
            <StackPanel Width="804" Height="574">
                <Grid DataContext="{Binding CurrentMonitor}" Margin="10 0" Height="auto">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" MinHeight="23" />
                        <RowDefinition Height="Auto" MinHeight="23" />
                        <RowDefinition Height="Auto" MinHeight="23" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="140" />
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Grid.Row="15"  Content="Serial Number" x:Name="SerialNumber"   />
                    <WrapPanel  DataContext="{Binding MonitorMainViewModel}" HorizontalAlignment="Center" Margin="0,10,0,10" Grid.ColumnSpan="2" Grid.Row="6" >
                        <Button Content="Add" Width="60" Margin="0,0,40,0" Command="{Binding ElementName=MonitorParent, Path=DataContext.AddConfidenceCommand}" />
                        <Button Content="Delete" Width="60" Margin="30,0,0,0" Command="{Binding ElementName=MonitorParent, Path=DataContext.DeleteConfidenceCommand}"/>
                    </WrapPanel>
    
                     ........