How is the DataContext inherited in Views that contains Views?

I am rebuilding the Josh Smith WPF CommandSink example , and there are a few things that I don’t understand about its data binding, especially how the datacontext is inherited when the view is contained in another view that is contained in a window that has a datacontext.

  • all data bindings are declared in XAML files, there is absolutely no code outside the window or any of the views (nice)
  • the top window defines its DataContext as a CommunityViewModel and simply displays the CommunityView
  • Question: so now in CommunityViewModel, what does it jas:CommandSinkBinding.CommandSink="{Binding}"really do? "CommandSink" is an attached property, so is it "attaching" an inherited binding that comes from DemoWindow, how is the value of the nested "CommandSink" property in a CommandSinkBinding?

  • Question: also, PersonView does not seem to have a DataContext, but has rows such as <TextBlock Text="{Binding Name}" Width="60" />which assume the binding is set. So does PersonView automatically get a binding from a string in CommunityView ItemsSource="{Binding People}"?

Thanks for any clarification here.

DemoWindow.xaml:

<Window 
  x:Class="VMCommanding.DemoWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:view="clr-namespace:VMCommanding.View"
  xmlns:vm="clr-namespace:VMCommanding.ViewModel"
  FontSize="13"
  ResizeMode="NoResize"
  SizeToContent="WidthAndHeight" 
  Title="ViewModel Commanding Demo"   
  WindowStartupLocation="CenterScreen"
  >
  <Window.DataContext>
    <vm:CommunityViewModel />
  </Window.DataContext>

  <Window.Content>
    <view:CommunityView />
  </Window.Content>
</Window>

CommunityView.xaml:

<UserControl 
  x:Class="VMCommanding.View.CommunityView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:jas="clr-namespace:VMCommanding"
  xmlns:view="clr-namespace:VMCommanding.View"
  xmlns:vm="clr-namespace:VMCommanding.ViewModel"  
  jas:CommandSinkBinding.CommandSink="{Binding}"
  >
    <UserControl.CommandBindings>
        <jas:CommandSinkBinding Command="vm:CommunityViewModel.KillAllMembersCommand" />
    </UserControl.CommandBindings>

    <DockPanel Margin="4">
        <ItemsControl
      DockPanel.Dock="Bottom" ItemsSource="{Binding People}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <view:PersonView />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button 
      Command="vm:CommunityViewModel.KillAllMembersCommand"
      Content="Kill All"
      Margin="0,0,0,8"
      />
    </DockPanel>
</UserControl>

PersonView.xml:

<UserControl 
  x:Class="VMCommanding.View.PersonView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:jas="clr-namespace:VMCommanding"
  xmlns:vm="clr-namespace:VMCommanding.ViewModel"
  jas:CommandSinkBinding.CommandSink="{Binding}"
  >  
  <UserControl.CommandBindings>
    <jas:CommandSinkBinding Command="vm:PersonViewModel.DieCommand" />
    <jas:CommandSinkBinding Command="vm:PersonViewModel.SpeakCommand" />
  </UserControl.CommandBindings>

  <UserControl.Resources>
    <Style TargetType="{x:Type TextBlock}">
      <Setter Property="Margin" Value="0,0,6,0" />
      <Style.Triggers>
        <DataTrigger Binding="{Binding CanDie}" Value="False">
          <Setter Property="Foreground" Value="#88000000" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </UserControl.Resources>

  <StackPanel Margin="2" Orientation="Horizontal">
    <TextBlock Text="Name:" FontWeight="Bold" />
    <TextBlock Text="{Binding Name}" Width="60" />
    <TextBlock Text="Age:" FontWeight="Bold" />
    <TextBlock Text="{Binding Age}" Width="40" />
    <Button 
      Command="vm:PersonViewModel.SpeakCommand"
      CommandParameter="Howdy partner!"
      Content="Speak"
      Margin="0,0,6,0"
      Width="60"
      />
    <Button
      Command="vm:PersonViewModel.DieCommand"
      Content="Die"
      Width="60"
      />
  </StackPanel>
</UserControl>
+3
source share
4

ItemsSource ItemsControl, DataContexts ItemsSource.

+4

DataContext, . - .

+3

PersonView DataTemplate ItemsControl CommunityView (CommunityView.xaml: 16).

DataTemplates DataContext , . WPF.

CommunityView DataContext .

sink CommandSink CommandSinkBinding, CommandBindings . , CommunityView.xaml CommandSink CommandSinkBindings CommunityView (KillAll) DataContext .

CommandSink Execute CanExecute ( ViewModel).

+1

DataContext - FrameworkElement ( WPF) DependencyProperty. , - DataContext.

0

Source: https://habr.com/ru/post/1706882/


All Articles