Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

wpf - TreeViewItem With Stretch

I want to create a WPF TreeView that contains TreeViewItems that stretch to fill the available space. I modified the TreeViewItem template using this as a guide: https://social.msdn.microsoft.com/Forums/vstudio/en-US/cabcb3ba-80c0-4367-85b7-9b55adc81e65/stretch-treeview-items?forum=wpf and this works well as I want the one character grid components on the right hand side to be right aligned and for the long TextBlock to take up the available space - see code below where the header for one of my TreeViewItems is a grid.

However, when I resize the window by dragging on the right hand side towards the left hand side, when there isn't enough space for all the grid components, I was expecting the long TextBlock with content "A long, long, ..." to start to shrink in width, but instead the TextBlocks on the right hand side get cut off by the right hand side window edge.

If I create a completely new example featuring a grid and put the grid mentioned above inside one of the grid cells (essentially emulating the grid that is used in the TreeView template) then it resizes as I expect: the TextBlock shrinks in width as I resize.

Any ideas what changes I can make to either the TreeViewItem template or the Header I have specified to get the resizing behavior I want?

<Window x:Class="TreeViewSimple3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TreeViewSimple3"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>
    <ControlTemplate x:Key="TreeViewItemStretchControlTemplate" TargetType="{x:Type TreeViewItem}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition MinWidth="19" Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}">
                <ToggleButton.Style>
                    <Style TargetType="{x:Type ToggleButton}">
                        <Setter Property="Focusable" Value="False"/>
                        <Setter Property="Width" Value="16"/>
                        <Setter Property="Height" Value="16"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ToggleButton}">
                                    <Border Background="Transparent" Height="16" Padding="5" Width="16">
                                        <Path x:Name="ExpandPath" Data="M0,0 L0,6 L6,0 z" Fill="Transparent" Stroke="#FF989898">
                                            <Path.RenderTransform>
                                                <RotateTransform Angle="135" CenterY="3" CenterX="3"/>
                                            </Path.RenderTransform>
                                        </Path>
                                    </Border>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsChecked" Value="True">
                                            <Setter Property="RenderTransform" TargetName="ExpandPath">
                                                <Setter.Value>
                                                    <RotateTransform Angle="180" CenterY="3" CenterX="3"/>
                                                </Setter.Value>
                                            </Setter>
                                            <Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
                                            <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
                                        </Trigger>
                                        <Trigger Property="IsMouseOver" Value="True">
                                            <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF1BBBFA"/>
                                            <Setter Property="Fill" TargetName="ExpandPath" Value="Transparent"/>
                                        </Trigger>
                                        <MultiTrigger>
                                            <MultiTrigger.Conditions>
                                                <Condition Property="IsMouseOver" Value="True"/>
                                                <Condition Property="IsChecked" Value="True"/>
                                            </MultiTrigger.Conditions>
                                            <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
                                            <Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
                                        </MultiTrigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ToggleButton.Style>
            </ToggleButton>
            <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Grid.ColumnSpan="2" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                <ContentPresenter x:Name="PART_Header" ContentSource="Header"
                HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>

            </Border>
            <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="TreeViewItem.IsExpanded" Value="false">
                <Setter TargetName="ItemsHost" Property="UIElement.Visibility" Value="Collapsed"/>
            </Trigger>
            <Trigger Property="ItemsControl.HasItems" Value="false">
                <Setter TargetName="Expander" Property="UIElement.Visibility" Value="Hidden"/>
            </Trigger>
            <Trigger Property="TreeViewItem.IsSelected" Value="true">
                <Setter TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"
                    Property="Border.Background"/>
                <Setter Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"
                    Property="Control.Foreground"/>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="TreeViewItem.IsSelected" Value="true"/>
                    <Condition Property="TreeViewItem.IsSelectionActive" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter TargetName="Bd"
                    Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"
                    Property="Border.Background"/>
                <Setter Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"
                    Property="Control.Foreground"/>
            </MultiTrigger>
            <Trigger Property="UIElement.IsEnabled" Value="false">
                <Setter Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" Property="Control.Foreground"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</Window.Resources>

<TreeView>
    <TreeViewItem Header="Parent" Template="{StaticResource TreeViewItemStretchControlTemplate}" HorizontalContentAlignment="Stretch">
        <TreeViewItem Template="{StaticResource TreeViewItemStretchControlTemplate}" HorizontalContentAlignment="Stretch">
            <TreeViewItem.Header>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" Text="A long, long, long, long, long, long, long label."/>
                    <StackPanel Grid.Column="1" Orientation="Horizontal">
                        <TextBlock Text="A"/>
                        <TextBlock Text="B"/>
                        <TextBlock Text="C"/>
                        <TextBlock Text="D"/>
                    </StackPanel>
                </Grid>
            </TreeViewItem.Header>
        </TreeViewItem>
    </TreeViewItem>
</TreeView>

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When I try code sample and reduce window size, TreeView shows horizontal scrollbar (because it has not only Grid but also ScrollViewer in its template)

try the following settings:

<TreeView ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 

to disable scroll

<TextBlock TextWrapping="Wrap" Grid.Column="0" ...> 

to enable word wrap.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...