4 Stimmen

Wie wird DataContext in Ansichten vererbt, die Ansichten enthalten?

Ich baue um Josh Smiths WPF CommandSink Beispiel und es gibt ein paar Dinge, die ich nicht verstehen, über seine databinding, vor allem über wie datacontext vererbt wird, wenn eine Ansicht in einer anderen Ansicht enthalten ist, die in einem Fenster, das einen datacontext hat enthalten ist.

  • alle Datenbindungen werden in den XAML-Dateien deklariert, es gibt absolut keinen Code hinter dem Fenster oder einer der Ansichten (schön)

  • das obere Fenster definiert seinen DataContext als CommunityViewModel und zeigt einfach die CommunityView an

  • Frage: Was bedeutet nun im CommunityViewModel die jas:CommandSinkBinding.CommandSink="{Binding}" tatsächlich tun? "CommandSink" ist eine angehängte Eigenschaft, so ist dies "anhängen" die geerbte Bindung, die von DemoWindow als Wert der angehängten Eigenschaft namens "CommandSink" auf das CommandSinkBinding-Objekt kommt?

  • Frage: auch PersonView scheint nicht zu einem DataContext noch hat es Zeilen wie <TextBlock Text="{Binding Name}" Width="60" /> die davon ausgehen, dass eine Bindung gesetzt ist. Bekommt PersonView also automatisch seine Bindung aus der Zeile in CommunityView ItemsSource="{Binding People}" ?

Vielen Dank für jede Klarstellung.

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>

4voto

Botz3000 Punkte 38010

Wenn Sie die Einstellung ItemsSource eines ItemsControls werden die DataContexts der Elemente in diesem Steuerelement direkt auf die Elemente des ItemsSource .

3voto

Farawin Punkte 1325

Ein Steuerelement erbt den übergeordneten DataContext, es sei denn, ein solcher wird explizit für das Steuerelement angegeben. Die Antwort auf Ihre zweite Frage lautet also ja.

1voto

Josh G Punkte 13806

PersonView wird durch das DataTemplate für das ItemsControl in CommunityView erzeugt (CommunityView.xaml:16).

DataTemplates weisen den DataContext ihres Bildmaterials automatisch den Daten zu, die die Vorlage anzeigt. So funktioniert WPF.

CommunityView erhält seinen DataContext durch Vererbung vom Window.

Die angehängte CommandSink-Eigenschaft setzt die Instanz CommandSink-Eigenschaft auf alle CommandSinkBinding-Objekte, die in der CommandBindings-Eigenschaft des Objekts mit der angehängten Eigenschaftszuweisung enthalten sind. In CommunityView.xaml wird also die CommandSink-Eigenschaft aller CommandSinkBindings in CommunityView (KillAll) durch Bindung auf den DataContext der Ansicht gesetzt.

Die CommandSink-Eigenschaft wird verwendet, um die Funktionen Execute und CanExecute auf dem richtigen Ziel (in diesem Fall dem ViewModel) aufzurufen.

0voto

Vasu Balakrishnan Punkte 1723

DataContext ist eine Eigenschaft von FrameworkElement (Basisklasse für alle WPF-Steuerelemente) und ist als DependencyProperty implementiert. Das bedeutet, dass alle abhängigen Elemente im logischen Baum denselben DataContext teilen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X