Почему TreeView не выбирает DataTemplates для дочерних узлов автоматически после определения TreeView.ItemTemplate?

Я не понимаю, что здесь делает wpf (используя .NET 3.5 с С#):

в моих ресурсах приложения я определил несколько шаблонов данных и иерархических шаблонов данных для разных типов моделей представления. Пока это работает хорошо, и TreeView в моем окне показывает узлы, как и ожидалось. Я должен сказать, что все дочерние элементы в каждой ViewModel появились как ICollectionView. Теперь я решил использовать особенности ICollectionView для группировки, сортировки и фильтрации «корневых узлов» TreeView. Я сделал TreeView таким:

<TreeView ItemsSource="{Binding Path=Elements.Groups}">
  <TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Path=Items}" ItemTemplate="{StaticResource SOMEITEMTEMPLATENAME}">
      <TextBlock Text="{Binding Path=Name}"/>
    </HierarchicalDataTemplate>
  </TreeView.ItemTemplate>
</TreeView>

ViewModel выглядит так:

class RootViewModel
  : INotifyPropertyChanged
{

  public ICollectionView Elements
  {
     get
     {
       ICollectionView view = CollectionViewSource.GetDefaultView(_elementsFromModel.Select(x => new FirstChildViewModel(x));
       view.GroupDescriptions.Add(new PropertyGroupDescription("Name"));
       view.Filter = delegate(Object x) { /*do some filter stuff here*/ };

       return view;
     }
  }
}

class FirstchildViewModel
  : INotifyPropertyChanged
{
  /*some other stuff here*/

  public ICollectionView Items
  {
    get;
  }
}

Теперь проблема заключается в том, что TreeView не выбирает автоматически правильные шаблоны для более глубоких дочерних элементов. Так что же в этом плохого?


person bolia    schedule 23.01.2013    source источник


Ответы (2)


Вы явно определили TreeView.ItemTemplate, поэтому WPF будет использовать только этот ItemTemplate. Вы должны определить свой HierarchicalDataTemplate для типа, который соответствует типу элемента Groups.

Но самый простой способ определить группу — определить свойство GroupStyle. вы можете узнать больше о функциях ICollectionView на странице msdn.

person stukselbax    schedule 23.01.2013
comment
Если вы используете свойство TreeView.GroupStyle, TreeView выглядит как ListView, а не как TreeView. Мне нужна возможность расширять и сворачивать дочерние узлы. - person bolia; 23.01.2013
comment
Для этой цели можно использовать Expander. Вы можете попробовать первое мое предложение — переместить HierarchicalDataTemplate в ресурсы и не задавать явно ItemTemplate. - person stukselbax; 23.01.2013
comment
Я даю ему ty, не знаю, что было не так в первый раз, но если я определяю GroupStyle.HeaderTemplate, это работает, единственное, что я не могу развернуть и свернуть корневые узлы. Может быть, HierarchicalDataTemplate нужно определить по-другому? - person bolia; 23.01.2013

Лучшим решением после некоторых исследований было бы определить TreeView следующим образом:

<TreeView ItemsSource="{Binding Path=Elements}">
  <TreeView.GroupStyle>
    <GroupStyle>
      <GroupStyle.ContainerStyle>
        <Style TargetType="{x:Type GroupItem}">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type GroupItem}">
                <TreeViewItem>
                  <TreeViewItem.Header>
                    <TextBlock Text="{Binding Path=Name}"/>
                  </TreeViewItem.Header>

                  <ItemsPresenter Margin="-20,0,0,0"/>
                </TreeViewItem>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </GroupStyle.ContainerStyle>
    </GroupStyle>
  </TreeView.GroupStyle>
</TreeView>

теперь узлы группы могут разворачиваться и сворачиваться, а разные дочерние узлы используют разные шаблоны данных. Спасибо @stukselbax за то, что указал мне правильное направление.

person bolia    schedule 23.01.2013