C# 缩进wpf树视图中的顶级层次项目

C# 缩进wpf树视图中的顶级层次项目,c#,wpf,treeview,C#,Wpf,Treeview,我试图在WPFTreeView中的顶级层次项目之间提供分隔(边距)。问题是,我不知道如何编写样式,使其仅适用于最上面的项目,而不适用于所有项目 myTreeView的代码如下所示: <TreeView ItemContainerStyle="{StaticResource treeViewItemStyle}" ItemsSource="{Binding Container.RootRules}" KeyUp="treeView_KeyUp"

我试图在WPF
TreeView
中的顶级层次项目之间提供分隔(边距)。问题是,我不知道如何编写
样式
,使其仅适用于最上面的项目,而不适用于所有项目

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


treevieItem
没有要使用的
Level
属性

因此,您有两种选择:

1) 。看看
TreeLevelConverter
,它很有趣。它们绑定控件本身并使用转换器检索
级别
。在您的情况下,您可以扩展转换器,以便在它检索到
级别
后,在
厚度
实例中将其转换为
边距

2) 您可以在
ViewModels
上创建
Level
属性(可能在其基类中,以避免代码重复)。然后,每次将子节点添加到
ViewModel
节点时,都会在该子节点上设置
级别。在xaml中,使用转换器将
边距
属性绑定到
视图模型
上的
级别
,该转换器根据
级别
是否为1返回不同的
厚度

编辑:

这就是为所有
树视图项设置公共
样式的方式:

<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
标题中的对象类型。
代码如下所示:

<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>
<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>
            <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
是我的自定义转换器,它将对象类型转换为字符串值。

您不能在HierarchicalDataTemplate中为RootRulesViewModel设置一个适当的网格边距吗?我尝试过,但它只会将边距添加到项目本身,因此项目会下移,但左边的箭头仍在原来的位置。这样看起来确实不太好。你可以使用
0,5
(即底部和顶部的值为5)的边距,而不是
0,10,0,0
。这解决了标题和标记之间对齐的问题,但也增加了顶部节点和以下子节点之间的间距,这不是我想要的。看起来这么简单的事情怎么会这么难实现呢?谢谢你的回答。这里的问题是:如何访问我的
treevieItem
样式上的属性?谢谢,现在已经清楚了。看起来这比我已经实现的基于头类型的解决方案要稍微多一些,但是如果只有一个层次模板,这将非常有用。我将把这个标记为答案,因为它会起作用。谢谢你的帮助。