DataContext如何在包含Views的Views中继承?

时间:2009-04-22 09:45:28

标签: c# wpf mvvm datacontext

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

  • 所有数据绑定都是在XAML文件中声明的,窗口后面绝对没有代码或任何一个视图(不错)
  • 顶部窗口将其DataContext定义为CommunityViewModel,只显示CommunityView
  • 问题:所以现在在CommunityViewModel中,jas:CommandSinkBinding.CommandSink="{Binding}"实际上做了什么? “CommandSink”是一个附加属性,所以这是“附加”来自DemoWindow的继承Binding,作为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>

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>

4 个答案:

答案 0 :(得分:4)

如果设置ItemsControl的ItemsSource,则该控件中项目的DataContexts将直接映射到ItemsSource的项目。

答案 1 :(得分:3)

控件继承它的父DataContext,除非为控件明确指定了一个。所以第二个问题的答案是肯定的。

答案 2 :(得分:1)

PersonView由社区视图中的ItemsControl的DataTemplate生成(CommunityView.xaml:16)。

DataTemplates自动将其视觉效果的DataContext分配给模板显示的数据。这就是WPF的工作方式。

CommunityView通过Window的继承来获取其DataContext集。

附加的命令接收器属性在具有附加属性赋值的对象的CommandBindings属性中包含的所有CommandSinkBinding对象上设置实例CommandSink属性。因此,在CommunityView.xaml中,CommunityView(KillAll)中所有CommandSinkBindings的CommandSink都通过绑定设置为视图的DataContext。

CommandSink属性用于调用正确目标上的Execute和CanExecute函数(在本例中为ViewModel)。

答案 3 :(得分:0)

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