【问题标题】:How to make Text Wrap in TreeviewItem?如何在 TreeviewItem 中进行文本换行?
【发布时间】:2018-05-12 09:41:41
【问题描述】:

编辑Francesco B. 下面给出的解决方案是有效的。我想知道是否还有 XAML 解决方案。

我想将 TreeViewItem 内的 TextBlock 中的文本进行换行。 我尝试了来自this 链接的解决方案。它会使 Header 文本换行,但不会使展开的 TextBlock。

这是我的带有父网格的 TreeView:

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

这是从 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>

我在边框中添加了Grid.ColumnSpan="2" 作为另一种解决方案,但这只会包裹标题。 我觉得我必须对 ItemsPresender 做点什么。但没有任何效果!

请提出解决方案!

谢谢。

【问题讨论】:

    标签: c# wpf treeview


    【解决方案1】:

    我能想到的最快的方法主要是使用代码隐藏。 它只需要为外部GridTreeView 添加一个名称,我从中删除了样式声明:

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

    然后,在代码隐藏中,我添加了一个方法来调整每个 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;
        }
    }
    

    然后,使用这个solution,我在第一次显示Window 时添加了一个对调整TreeView 大小的方法的调用:

    private bool _shown = false;
    
    public MainWindow()
    {
        InitializeComponent();
    }
    
    protected override void OnContentRendered(EventArgs e)
    {
        base.OnContentRendered(e);
        if (_shown)
        {
            return;
        }
    
        _shown = true;
        ResizeTree();
    }
    

    最后我添加了一个在移动GridSplitter 时引发的事件:

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

    其中当然要调用ResizeTree方法:

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

    其他可能需要处理的事情是调整窗口大小,或为页眉和项目使用不同的边距(我选择 30 和 60)。

    【讨论】:

    • 是的。正在工作中。我会用它。 +1。我想知道是否有 XAML 解决方案。
    【解决方案2】:

    要查看 XAML 解决方案,您可以尝试从 treeviewitem 模板中删除 ContentPresenter 并将其更改为具有所需属性的 TextBlock,例如 MaxWidth 和 TextWrapping,仅此而已。 如果您在模板 Text="{TemplateBinding Header}" 中设置 TextBlock,一切仍然有效。现在您不需要在每个 treeviewitem 中放置一个文本块 - 模板就在里面) 然后根据需要添加树视图项:使用 ItemsSource(在这种情况下,您可能还应该指定 DataTemplate)或就像

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

    或者从后面的代码,没关系。

    【讨论】:

    • 这似乎不起作用!用 TextBlock 替换 Template 中的 ContentPresenter 是可以的,但是如何将文本放在那里。无论如何,这是标题。我对物品感兴趣。也许您的意思是 Replace ItemsPresenter ?我也试过了,但我不知道如何填充它。
    • 我已经稍微编辑了我的答案以更准确地解释我的意思:) 你不应该替换 ItemsPresenter。如果这样做,您将只看到第一级树视图,而没有子节点。
    • 好的。我得到了它。我这样做了。它适用于标题文本块。我现在还需要的是子笔记的相同行为,它们是文本块!这可能吗?
    猜你喜欢
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 2010-10-29
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    相关资源
    最近更新 更多