Wpf 为什么';t TreeView在定义TreeView.ItemTemplate后自动为Childnodes选择数据模板?

Wpf 为什么';t TreeView在定义TreeView.ItemTemplate后自动为Childnodes选择数据模板?,wpf,mvvm,treeview,datatemplate,icollectionview,Wpf,Mvvm,Treeview,Datatemplate,Icollectionview,我不明白wpf在这里做什么(使用.NET3.5和C#): 在我的应用程序资源中,我为不同类型的ViewModel定义了几个DataTemplates和HierarchicalDataTemplates。到目前为止,它工作得很好,我窗口中的TreeView显示了预期的节点。我必须说,每个视图模型中的所有子元素都是ICollectionView。 现在我决定使用ICollectionView的特性,对TreeView的“根节点”进行分组、排序和过滤。 我让树视图看起来像这样: <TreeVie

我不明白wpf在这里做什么(使用.NET3.5和C#):

在我的应用程序资源中,我为不同类型的ViewModel定义了几个DataTemplates和HierarchicalDataTemplates。到目前为止,它工作得很好,我窗口中的TreeView显示了预期的节点。我必须说,每个视图模型中的所有子元素都是ICollectionView。 现在我决定使用ICollectionView的特性,对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>
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 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>

现在的问题是TreeView没有自动为更深层的子元素选择正确的模板。那么这有什么问题呢?

您已经明确定义了树视图.ItemTemplate,因此WPF将只使用该
项模板。您必须为类型定义您的层次结构数据模板,它对应于
元素类型


但是定义组的简单方法是定义
GroupStyle
属性。您可以在

上阅读有关ICollectionView功能的更多信息。经过一些研究后,最好的解决方案是如下定义树视图:

<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>
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 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为我指明了正确的方向。

如果使用TreeView.GroupStyle属性,则TreeView看起来像列表视图,不再像TreeView了。我需要扩展和折叠子节点的可能性。您可以使用Expander实现此目的。您可以尝试我的第一个建议-将HierarchycalDataTemplate移动到资源中,不要显式设置ItemTemplate。我给了它一个ty,不知道第一次出了什么问题,但是如果我定义了一个GroupStyle.HeaderTemplate,它可以工作,唯一的问题是我无法展开和折叠根节点。也许必须以另一种方式定义HierarchycalDataTemplate?