WPF Treeview 固定列宽

8
我想创建一个树形视图和列表视图的组合。我希望有两列。在左列中,我想要一个递归树形视图,右列应显示关于左列项目的一些信息。我们称左列为名称(Name),右列为值(Value)。问题在于,当展开树形视图时,缩进级别会发生变化,导致值列不对齐。
我能想到的解决方法是:
A: 使用内置的TreeView,并根据缩进级别手动更改Name列的宽度,以使Value列始终对齐。
B: 使用内置的ListView,并手动创建TreeView,通过在父项和子项之间添加子项并更改这些子项的缩进来实现。
真的没有更好的方法吗?
1个回答

7

有一种方法,我在Silverlight应用程序中有一个这样的“野兽”

您需要调整treeviewitem的模板。 默认模板无法完全扩展到整个树视图。

通过调整模板,您可以使其完全扩展,并且可以将DataTemplate(或HierarchicalDataTemplate)设置为网格。如果我没记错的话,您需要获取TreeviewItem的默认模板副本,并将“Header”元素的HorizontalAlignment属性更改为“Stretch”,删除组成模板的最右侧列,并将包含元素的列的宽度从“Auto”更改为“*”。

使用Blend很容易做到。创建一个TreeViewItem,在其上单击右键,然后选择“编辑控件部分(“模板”)>编辑副本...” 这将创建TreeviewItem的默认模板的副本。从那里,找到名为PART_Header的ContentPresenter。从此向上走,找到包含的网格并 修改其列以匹配我的解释(删除最后一列,将第二列从“Auto”更改为“*”)。 在为项目创建的样式中,将HorizontalContentAlignment设置为“Stretch”(默认情况下绑定到其他内容)。

将创建的样式用作树视图上的ItemContainerStyle。 之后,您可以删除最初创建的TreeViewItem。

最后,您应该得到一堆资源,其中一个是您的样式。请参见下面的内容,了解我最终得到的内容(TreeViewItem样式和带有名称和值列的项目的基本DataTemplate)。 TreeViewItem样式/模板引用的其他资源未在此处显示(因为它已经太长:p)。

<Window.Resources>    
<Style x:Key="TreeViewItemStyle1" TargetType="{x:Type TreeViewItem}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="Padding" Value="1,0,0,0"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TreeViewItem}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition MinWidth="19" Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" ClickMode="Press" IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"/>
                        <Border x:Name="Bd" SnapsToDevicePixels="true" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" x:Name="PART_Header" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header"/>
                        </Border>
                        <ItemsPresenter x:Name="ItemsHost" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsExpanded" Value="false">
                            <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
                        </Trigger>
                        <Trigger Property="HasItems" Value="false">
                            <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Property="IsSelectionActive" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

        <HierarchicalDataTemplate x:Key="DataTemplate1"                                   
                                  ItemsSource="{Binding SubNodes}">
            <Grid Margin="5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock HorizontalAlignment="Left"
                           VerticalAlignment="Top"
                           Grid.Column="1"
                           Text="HEADER"
                           TextWrapping="Wrap" />
                <TextBox HorizontalAlignment="Left"
                         Margin="2"
                         VerticalAlignment="Top"
                         Text="VALUE"
                         TextWrapping="Wrap"
                         Grid.Column="2" />
            </Grid>

</Window.Resources>

<TreeView HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Width="Auto"
                  Height="Auto"
                  x:Name="trv"
          ItemContainerStyle="{StaticResource TreeViewItemStyle1}"
                  ItemTemplate="{DynamicResource DataTemplate1}">            
        </TreeView>

请注意,您需要确保包含右侧单元格的网格列始终具有相同的宽度,否则您将会看到一些奇怪的东西(我使用带有固定宽度内容的“自动”列,并在名称和“单元格”之间添加空白“*”列以使其右对齐)。
另请注意,此解决方案基本上将树形视图的外观“冻结”到您机器上的任何主题。 (它将根据您在修改时使用的操作系统在Vista和XP机器上看起来相同)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接