4

我正在重建Josh Smith 的 WPF CommandSink 示例,关于他的数据绑定,我有一些不明白的地方,尤其是当一个视图包含在另一个视图中时如何继承数据上下文,而另一个视图包含在具有数据上下文的窗口中。

  • 所有数据绑定都在 XAML 文件中声明,窗口或任何一个视图后面绝对没有代码(很好)
  • 顶部窗口将其 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>

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>

人视图.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

4 回答 4

4

如果设置ItemsSourceItemsControl 的 ,则该控件中项的 DataContext 将直接映射到ItemsSource.

于 2009-04-22T11:25:12.567 回答
3

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

于 2009-04-22T09:52:02.867 回答
1

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

DataTemplates 自动将其视觉对象的 DataContext 分配给模板正在显示的数据。这就是 WPF 的工作原理。

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

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

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

于 2009-04-22T12:25:53.323 回答
0

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

于 2009-06-09T16:54:24.480 回答