1

Edit : The solution given below from Francesco B. is working. I was wondering if there is an XAML solution also.

I would like to make the Text in TextBlock inside a TreeViewItem to Wrap. I tried the solution from this link. It will make the Header text wrap, but not the expanded TextBlock.

Here is my TreeView with the parent Grid:

<Grid Background="LightGray">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Grid Grid.Column="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <TreeView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <TreeViewItem Style="{DynamicResource TreeViewItemStyle1}">
                <TreeViewItem.Header>

                    <TextBlock Text="Header Header Header Header Header Header Header Header "
                               TextWrapping="Wrap" />

                </TreeViewItem.Header>
                <TextBlock Text="1very 2very 3very 4very 5long 6very 7very 8very 9very 10Long"
                           TextWrapping="Wrap"
                           Background="LightCyan" />

            </TreeViewItem>
        </TreeView>

    </Grid>

    <GridSplitter Grid.Column="1"
                  Width="10"
                  ResizeBehavior="PreviousAndNext" />
    <Grid Grid.Column="2"
          Background="LightPink" />
</Grid>

Here is the part of the changed Template from TreeViewItemStyle1:

                            <Border x:Name="Bd"
                                BorderBrush="Red"
                                BorderThickness="1"
                                Background="{TemplateBinding Background}"
                                Grid.Column="1"
                                Grid.ColumnSpan="2"
                                Grid.Row="0"
                                Padding="{TemplateBinding Padding}"
                                SnapsToDevicePixels="true">
                            <ContentPresenter x:Name="PART_Header"
                                              ContentSource="Header"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Border>
                        <ItemsPresenter x:Name="ItemsHost"
                                        ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                                        TextBlock.FontSize="35"
                                        Grid.Column="1"
                                        Grid.ColumnSpan="2"
                                        Grid.Row="1">
                        </ItemsPresenter>

I added Grid.ColumnSpan="2" to the border as the other solution, but this makes only header to be Wraped. I feel like i have to do something with ItemsPresender. But nothing works!

Please suggest a solution!

Thanks.

Prodromos
  • 146
  • 2
  • 10

2 Answers2

1

The quickest thing I can think of mostly uses code-behind. It just requires adding a name to the outer Grid and the TreeView, from which I removed the style declaration:

<Grid  x:Name="MyGrid" Background="LightGray" >
...
<TreeView x:Name="MyTree" ScrollViewer.HorizontalScrollBarVisibility="Disabled">

Then, in the code-behind I added a method to resize both header and item of each TreeViewItem:

private void ResizeTree()
{
    var MaxWidth = Convert.ToDouble(MyGrid.ColumnDefinitions[0].ActualWidth);
    foreach (TreeViewItem item in MyTree.Items)
    {
        var Header = item.Header as TextBlock;
        var Body = item.Items[0] as TextBlock;
        Header.Width = MaxWidth - 30;
        Body.Width = MaxWidth - 60;
    }
}

Then, using this solution, I added a call to the method to resize the TreeView when the Window is shown for the first time:

private bool _shown = false;

public MainWindow()
{
    InitializeComponent();
}

protected override void OnContentRendered(EventArgs e)
{
    base.OnContentRendered(e);
    if (_shown)
    {
        return;
    }

    _shown = true;
    ResizeTree();
}

Last I added an event to be raised when the GridSplitter is moved:

<GridSplitter Grid.Column="1" DragCompleted="GridSplitter_DragCompleted"
              Width="10" ResizeBehavior="PreviousAndNext" />

which of course has to call the ResizeTree method:

private void GridSplitter_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
    ResizeTree();
}

Other things to possibly deal with are Window resizing, or using a different margin for header and item (I choose 30 and 60).

Francesco B.
  • 2,729
  • 4
  • 25
  • 37
1

To see the XAML solution you just can try to remove ContentPresenter from treeviewitem template and change it to TextBlock with needed properties, like MaxWidth & TextWrapping, and that's it. If you set on TextBlock in template Text="{TemplateBinding Header}" everything still works. And now you don't need to put a textblock inside each treeviewitem - template just has it inside) Then you add treeviewitems as you wish: using ItemsSource (in this case you probably should also specify DataTemplate) or just like

<TreeView> <TreeViewItem Header="first"/><TreeViewItem Header="second"/>...</TreeView> 

Or from back code, it doesn't matter.

Maryna Klokova
  • 431
  • 7
  • 14
  • This doesn't seem to work! Replacing ContentPresenter in Template with a TextBlock is ok, but how to put text there. Anyway this is the Header. I'm Interested for Items. Maybe you mean Replace ItemsPresenter ? I tried this also but, I don't know how to populate this. – Prodromos May 13 '18 at 11:29
  • I've edited my answer a little to explain more properly what I mean :) You should'nt replace ItemsPresenter. If you do, you will see only first level of treeview, and no child nodes. – Maryna Klokova May 13 '18 at 11:43
  • Ok. I got it. i did this. It's working for the header textblock. What i need also now is the same behavior for the child notes, which are textblocks! Is that possible ? – Prodromos May 13 '18 at 18:20