Gopichandar
Gopichandar

Reputation: 2832

Wrap TextBlock content of TreeviewItem in Treeview

I'm trying to wrap content of item over the Treeview without Horizontal scrollbar still yet to discover the optimal solution.

Here is the sample code snippet which I'm working with

   <TreeView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <TreeViewItem IsExpanded="True">
            <TreeViewItem.Header>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType=TreeView}, Path=ActualWidth}"/>                            
                    </Grid.ColumnDefinitions>
                    <TextBlock TextWrapping="Wrap" Text="Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here " />
                </Grid>
            </TreeViewItem.Header>
            <TreeViewItem>
                <TreeViewItem.Header>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType=TreeView}, Path=ActualWidth}"/>                                
                        </Grid.ColumnDefinitions>
                        <TextBlock TextWrapping="Wrap" Text="Level 2.1 Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here " Foreground="Blue" />
                    </Grid>
                </TreeViewItem.Header>
            </TreeViewItem>               
        </TreeViewItem>
    </TreeView>

and the output is

enter image description here

You can see the content exceeds the view. I know this is because we are setting the Treeview width and TreeviewItem has some indentation but how can I get the optimal width for TreeviewItem?

Already tried the following links without any luck.

Upvotes: 2

Views: 1130

Answers (2)

mm8
mm8

Reputation: 169210

Each TreeViewItem has a minimum indentation of about 19 DIP - this is a hardcoded value in the default ControlTemplate - so you could increase the right-margin by this value + some offset for each level:

<TreeView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <TreeViewItem IsExpanded="True">
        <TreeViewItem.Header>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType=TreeView}, Path=ActualWidth}"/>
                </Grid.ColumnDefinitions>
                <TextBlock TextWrapping="Wrap" Text="Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here "
                                   Margin="0 0 25 0"/>
            </Grid>
        </TreeViewItem.Header>
        <TreeViewItem>
            <TreeViewItem.Header>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType=TreeView}, Path=ActualWidth}"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock TextWrapping="Wrap" Text="Level 2.1 Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here Level 1 (Blue) Some long text over here " Foreground="Blue"
                                       Margin="0 0 50 0"/>
                </Grid>
            </TreeViewItem.Header>
        </TreeViewItem>
    </TreeViewItem>
</TreeView>

If you want to be able to do this dynamically, you could handle the Loaded event of the TextBlock in the HierarchicalDataTemplate and calculate the Margin based on the level of the TreeViewItem container. Something like this:

<TreeView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:YourType}" ItemsSource="{Binding Children}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType=TreeView}, Path=ActualWidth}"/>
                </Grid.ColumnDefinitions>
                <TextBlock TextWrapping="Wrap" Text="{Binding Header}" Foreground="Blue" 
                           Loaded="TextBlock_Loaded" />
            </Grid>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

private void TextBlock_Loaded(object sender, RoutedEventArgs e)
{
    TextBlock textBlock = sender as TextBlock;
    TreeViewItem tvi = FindParent<TreeViewItem>(textBlock);
    ItemsControl parent = ItemsControl.ItemsControlFromItemContainer(tvi);
    int index = 1;
    while (parent != null && parent.GetType() == typeof(TreeViewItem))
    {
        index++;
        parent = ItemsControl.ItemsControlFromItemContainer(parent);
    }

    textBlock.Margin = new Thickness(0, 0, 25 * index, 0);
}

Upvotes: 2

Daniele Sartori
Daniele Sartori

Reputation: 1703

You can try to set the width of TreeviewItem getting the actual width of the control that own the treeview or the treeView itself

in xaml:

 Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeView //or x:Type ControlThatOwnTreeView}}, Path=ActualWidth

Upvotes: 0

Related Questions