2014-01-14 1 views
5

Я чувствую, что мне не хватает какой-то существенной концепции в привязке WPF. Это всегда поражает, будут ли мои привязки работать для меня.Связывание с TreeViewItem.IsExpanded. Почему это работает?

В этом примере я хочу, чтобы двухсторонняя привязка свойства IsExpanded TreeViewItem к соответствующему свойству связанного объекта. Он работает с первым примером; он НЕ со вторым.

Может ли кто-нибудь объяснить, почему? Я не понимаю, почему вторая версия не работает. И я не могу не думать, что это спасло бы меня несказанное горе, если бы я мог.

Это работает при помещении в UserControl.Resources (привязка к IsExpanded делается с помощью стиля, приложенного к TreeViewItem:

<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> 

Это не (прямое связывание с IsExpanded в шаблоне данных):

<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> 

DataTemplate используется в следующем фрагменте Xaml, с приведенным выше шаблоном данных, используемым для выполнения преобразования данных. Документы являются наблюдаемым списком FolderItems, который был связан правильно.

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

Оба DataTemplates отображают дерево файлов. Но нет привязки (двусторонней или иной) для IsExpanded во втором случае.

не показан DataTemplating для FileItem ', которые листовые узлы FolderItem с ..

ответ

8

Вопрос заключается в том, что TreeViewItem фактически является оболочкой, которая используется в самом TreeView. Он не должен (и не должен) быть частью вашего DataTemplate, так как теперь у вас есть TreeViewItem в пределах TreeViewItem (внешняя создается TreeView, а внутренняя часть является частью шаблона).

Вот почему ваш стиль работы, так как он будет применяться к всеTreeViewItem с, как тот, который вы объявляя (который заканчивается тем, что бессмысленно) и один созданный TreeView.

Что вы должны сделать, это заменить DataTemplate с этим:

<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> 

(К сожалению, я не могу проверить в данный момент, но это должно, по крайней мере, чтобы вы движетесь в правильном направлении).

Оставьте свой стиль как есть, чтобы продолжить связывать свойство.

+2

Arg. Не показано в примере, было то, что у treeview был ItemTemplate, который имеет приоритет над DataTemplate. Но вы правы: Data Templating происходит до того, как элемент управления TreeView помещает обертку TreeViewItem вокруг объекта с шаблоном данных, а TreeViewItem (в отличие от других элементов управления) НЕ проверяет, является ли это TreeViewItem уже. Благодарю. Ослепленное существенным недоразумением, которое вы правильно указали. –

Смежные вопросы