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