4

Josh Smith の WPF CommandSink の例を再構築していますが、彼のデータ バインディングについて理解できないことがいくつかあります。特に、データ コンテキストを持つウィンドウに含まれる別のビューにビューが含まれている場合に、データ コンテキストがどのように継承されるかについてです。

  • すべてのデータ バインディングは XAML ファイルで宣言されており、ウィンドウやビューの背後にコードはまったくありません (いいですね)。
  • 一番上の Window はその DataContext を CommunityViewModel として定義し、単に CommunityView を表示します
  • 質問: それでは、CommunityViewModel では、jas:CommandSinkBinding.CommandSink="{Binding}"実際に何をしますか? 「CommandSink」は添付プロパティなので、これは CommandSinkBinding オブジェクトの「CommandSink」と呼ばれる添付プロパティの値として DemoWindow から継承された Binding を「添付」していますか?

  • 質問:また、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

4 に答える 4

4

ItemsControlの を設定するItemsSourceと、そのコントロール内の項目の DataContext が の項目に直接マップされますItemsSource

于 2009-04-22T11:25:12.567 に答える
3

コントロールに対して明示的に指定されていない限り、コントロールは親の DataContext を継承します。したがって、2 番目の質問に対する答えは「はい」です。

于 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 (KillAll) 内のすべての CommandSinkBinding の CommandSink が、バインドによってビューの DataContext に設定されます。

CommandSink プロパティは、適切なターゲット (この場合は ViewModel) で Execute および CanExecute 関数を呼び出すために使用されます。

于 2009-04-22T12:25:53.323 に答える
0

DataContext は FrameworkElement (すべての WPF コントロールの基本クラス) のプロパティであり、DependencyProperty として実装されます。つまり、論理ツリー内のすべての子孫要素が同じ DataContext を共有します。

于 2009-06-09T16:54:24.480 に答える