2014-01-14 14 views
5

Ich habe das Gefühl, dass ich ein essenzielles Konzept in WPF Databinding vermisse. Es ist immer ein Treffer, ob meine Bindungen für mich funktionieren.Bindung an TreeViewItem.IsExpanded. Warum funktioniert das?

In diesem Beispiel möchte ich die IsExpanded-Eigenschaft eines TreeViewItem in zwei Richtungen an die entsprechende Eigenschaft eines gebundenen Objekts binden. Es funktioniert mit dem ersten Beispiel; es tut NICHT mit dem zweiten.

Kann jemand erklären warum? Ich kann nicht verstehen, warum die zweite Version nicht funktioniert. Und ich kann nicht anders als zu denken, dass es mir unbeschreibliche Trauer ersparen würde, wenn ich könnte.

<Style TargetType="TreeViewItem"> 
     <Setter Property="IsExpanded" 
       Value="{Binding Path=IsExpanded, Mode=TwoWay}" /> 
    </Style> 
    <DataTemplate DataType="{x:Type viewModels:FolderItem}"> 
     <TreeViewItem ItemsSource="{Binding Folders}" 
      IsExpanded="{Binding Mode=TwoWay,Path=IsExpanded}" > 
      <TreeViewItem.Header> 
       <StackPanel Orientation="Vertical"> 
        <Image Source="{Binding IconSource}" 
          Width="16" Height="16" 
          Margin="4,0,4,0" VerticalAlignment="Center" /> 
        <TextBlock Text="{Binding Title}" 
          VerticalAlignment="Center" /> 
       </StackPanel> 
      </TreeViewItem.Header> 
     </TreeViewItem> 
    </DataTemplate> 

Dies gilt nicht (direkte Bindung an IsExpanded in der Datenvorlage):

Dies, wenn sie in UserControl.Resources (Bindung an IsExpanded platziert arbeitet mit einem Style TreeViewItem angewendet getan

<DataTemplate DataType="{x:Type viewModels:FolderItem}"> 
     <TreeViewItem ItemsSource="{Binding Folders}" 
      IsExpanded="{Binding Path=IsExpanded,Mode=TwoWay}" > 
      <TreeViewItem.Header> 
       <StackPanel Orientation="Vertical"> 
        <Image Source="{Binding IconSource}" 
          Width="16" Height="16" Margin="4,0,4,0" 
          VerticalAlignment="Center" /> 
        <TextBlock Text="{Binding Title}" 
         VerticalAlignment="Center" /> 
       </StackPanel> 
      </TreeViewItem.Header> 
     </TreeViewItem> 
    </DataTemplate> 

Das DataTemplate wird im folgenden Xaml-Fragment verwendet, wobei die oben angegebene Datenvorlage für die Datenkonvertierung verwendet wird Dokumente ist eine beobachtbare Liste von FolderItems, die ordnungsgemäß gebunden wurden.

<TreeView ItemsSource="{Binding Documents}" /> 

Beide DataTemplates zeigen den Dateibaum. Aber im zweiten Fall gibt es für IsExpanded keine Bindung (zweiseitig oder anderweitig).

Nicht für FileItem der gezeigt wird DataTemplating, die die Blattknoten von FolderItem die sind ..

Antwort

8

Das Problem ist, dass TreeViewItem tatsächlich ein Wrapper ist, die durch die TreeView selbst verwendet wird. Es muss nicht (und sollte nicht) Teil Ihrer DataTemplate sein, denn was Sie jetzt haben, ist ein TreeViewItem innerhalb einer TreeViewItem (die äußere wird von der TreeView erstellt, und die innere ist ein Teil der Vorlage) zu erstellen. Diese

ist, warum Ihr Stil funktioniert, wie es zu alleTreeViewItem s angewendet wird, sowohl die eine, die Sie deklarieren (was ist sinnlos endet), und den von der TreeView erstellt.

Was Sie tun sollten, ersetzen Sie DataTemplate mit diesem:

<HierarchicalDataTemplate ItemsSource="{Binding Folders}"> 
    <StackPanel Orientation="Vertical"> 
     <Image Source="{Binding IconSource}" 
       Width="16" Height="16" Margin="4,0,4,0" 
       VerticalAlignment="Center" /> 
     <TextBlock Text="{Binding Title}" 
        VerticalAlignment="Center" /> 
<HierarchicalDataTemplate> 

(Leider kann ich zur Zeit nicht testen, aber das sollte zumindest erhalten Sie in die richtige Richtung).

Lassen Sie Ihren Stil unverändert, um die Eigenschaft zu binden.

+2

Arg. Nicht im Beispiel gezeigt, war, dass die Baumansicht auch eine ItemTemplate hatte, die Vorrang vor der DataTemplate hat. Aber Sie sind richtig: Data Templating tritt auf, bevor das TreeView-Steuerelement den TreeViewItem-Wrapper um das Data-Template-Objekt platziert, und das TreeViewItem (im Gegensatz zu anderen Steuerelementen) überprüft NICHT, ob es bereits ein TreeViewItem-Objekt ist. Vielen Dank. Geblendet von einem wesentlichen Missverständnis, auf das Sie richtig hingewiesen haben. –