代码之家  ›  专栏  ›  技术社区  ›  Edward Tanguay

在包含视图的视图中,如何继承DataContext?

  •  3
  • Edward Tanguay  · 技术社区  · 16 年前

    我正在重建 Josh Smith's WPF CommandSink example 关于他的数据绑定,我有一些事情我不理解,特别是当一个视图包含在另一个包含在具有数据上下文的窗口中的视图中时,数据上下文是如何继承的。

    • 所有数据绑定都在XAML文件中声明,窗口或任何一个视图后面都绝对没有代码(nice)
    • 顶部窗口将其DataContext定义为CommunityViewModel,并只显示CommunityView
    • 问题: 所以现在在CommunityViewModel中, jas:CommandSinkBinding.CommandSink="{Binding}" 真的吗?”commandSink是一个附加属性,所以这个“附加”继承的绑定来自demoWindow,它是commandSinkBinding对象上名为“commandSink”的附加属性的值吗?

    • 问题: 此外,PersonView似乎没有DataContext,但它有如下行: <TextBlock Text="{Binding Name}" Width="60" /> 假设设置了绑定。因此,PersonView是否自动从CommunityView中的行获取其绑定 ItemsSource="{Binding People}" ?

    感谢您的澄清。

    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>
    

    社区视图.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>
    
    4 回复  |  直到 13 年前
        1
  •  4
  •   Botz3000 Amir Sheng    13 年前

    如果你设置 ItemsSource 对于itemsControl,该控件中的项的数据上下文直接映射到 项目源 .

        2
  •  3
  •   Farawin    16 年前

    除非为控件显式指定了父DataContext,否则控件继承其父DataContext。所以第二个问题的答案是肯定的。

        3
  •  1
  •   Josh G    16 年前

    PersonView由CommunityView(CommunityView.xaml:16)中itemsControl的数据模板生成。

    数据模板自动将其视觉效果的数据上下文分配给模板显示的数据。这就是WPF的工作原理。

    CommunityView从窗口继承获取其DataContext集。

    附加的command sink属性为包含在具有附加属性分配的对象的commandBindings属性中的所有commandSinkBinding对象设置实例commandSink属性。因此,在communityView.xaml中,commandSink中所有commandSinkBindings(killall)的commandSink都通过绑定设置为视图的DataContext。

    commandSink属性用于在正确的目标(在本例中为viewModel)上调用execute和canexecute函数。

        4
  •  0
  •   Vasu Balakrishnan    16 年前

    DataContext是FrameworkElement(所有WPF控件的基类)上的属性,并作为DependencyProperty实现。这意味着逻辑树中的所有子代元素共享相同的数据上下文。