缩进wpf树视图中的顶层分层项
本文关键字:分层 wpf 视图 缩进 | 更新日期: 2023-09-27 18:05:23
我试图在WPF TreeView
的顶层分层项之间提供分离(边距)。问题是,我不知道如何编写Style
,使其仅适用于最上面的项目,而不是每个项目。
我的TreeView
的代码看起来像这样:
<TreeView ItemContainerStyle="{StaticResource treeViewItemStyle}"
ItemsSource="{Binding Container.RootRules}"
KeyUp="treeView_KeyUp"
SelectedItemChanged="TreeView_SelectedItemChanged">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type me:HybridForecastRulesViewModel}"
ItemsSource="{Binding Children}">
<Border Name="bd"
...
</Border>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type me:RootRulesViewModel}"
ItemsSource="{Binding Rules}">
<Grid>
...
</Grid>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
我有一个像这样的treeviewitem的样式:
<Style x:Key="treeViewItemStyle"
BasedOn="{StaticResource {x:Type TreeViewItem}}"
TargetType="{x:Type TreeViewItem}">
<Setter Property="Margin" Value="0,10,0,0" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
但是这个样式适用于两种类型的项目(RootRulesViewModel
和HybridForecastRulesViewModel
),当我希望它只适用于RootRulesViewModel
类型的项目时。如何做到这一点?
锦上添花的是,除了第一个项目,所有RootRulesViewModel
项目的top Margin
都为10。
TreeViewItem
没有Level
属性。
所以你有两个选项:
1)。看看TreeLevelConverter
,它很有趣。它们绑定控件本身并使用转换器检索Level
。在您的示例中,您可以扩展转换器,以便在它检索Level
之后,将其转换为Thickness
实例以用作Margin
。
2)你可以在你的ViewModels
上创建一个Level
属性(可能在它们的基类中,以避免代码重复)。然后,每次向ViewModel
节点添加子节点时,都要在该子节点上设置Level
。在xaml中,您将Margin
属性绑定到ViewModel
上的Level
,使用一个转换器,根据Level
是否为1返回不同的Thickness
。
这是如何为所有的TreeViewItem
设置一个通用的Style
:
<TreeView>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter 1 .../>
<Setter 2 .../>
<Setter Property="Margin"
Value="{Binding Level, Converter={StaticResource LevelToMarginConverter}}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<!-- here your hierarchical DataTemplate... -->
<HierarchicalDataTemplate ... />
</TreeView.Resources>
</TreeView>
我实际上已经有了一个解决方案。我不确定它有多好,所以我愿意听取建议来改进。
我从这个答案中编写了一个对象转换器,以获得TreeViewItem
的Header
中的对象类型。代码看起来像这样:
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Header, Converter={StaticResource ObjectTypeConverter}}"
Value="RootRulesViewModel">
<Setter Property="Margin"
Value="0,0,0,10" />
</DataTrigger>
<DataTrigger Binding="{Binding IsVisible}"
Value="False">
<Setter Property="Visibility"
Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
其中ObjectTypeConverter
是我的自定义转换器,它将对象类型转换为字符串值。