当TextBlock放置在ViewBox中时,文本不会自动换行。

14

我有一个长文本的TextBlock需要自动换行。我已经将TextBlock放在ViewBox中,期望随着文本大小的变化而实现自动换行,但实际上并没有发生。ViewBox只是调整TextBox的大小,以使所有文本都适合一行,从而使文本变得非常小。

我该如何使用ViewBox同时调整文本大小和实现自动换行?

以下是我的代码:

<Viewbox>
    <TextBlock Text="The Option text can also dynamically grow/shrink to fit more content. More text to go here....................." TextWrapping="Wrap"/>
</Viewbox>

这是 Windows 8 商店应用程序的一部分,因此是 WinRT Xaml。


可能会有帮助WPF:我们可以在ViewBox中制作两行吗? - Farhan Ghumra
不,那样行不通,但还是谢谢你的尝试。 - Sun
1
@Xyroid的链接帖子是正确的,但你需要以某种方式给TextBlock一个MaxWidth,这样它才会确定需要进行TextWrap。你可以在XAML中手动完成此操作,也可以在Viewbox Loaded事件中执行一些操作,找出渲染大小并将ChildMaxWidth设置为该大小。 - Nate Diamond
3个回答

31

只需在 TextBlock 上设置宽度即可。

        <Viewbox Width="500">
            <TextBlock Width="100" TextWrapping="Wrap">This is the text that's long and on two lines.</TextBlock>
        </Viewbox>

宽度为 100 的 TextBlock 在宽度为 500 的 ViewBox 中

因此,ViewBox 将缩放其所有内容。如果您没有通过在 TextBlock 上设置宽度来限制其内容,则 ViewBox 将为其提供无限空间进行扩展。您还可以在 ViewBox 中添加具有宽度和高度的根 Grid,并在其中布置您的元素,然后整个布局将根据 ViewBox 的宽度进行缩放。

在图像中,TextBlock 的宽度为 100,缩放到与宽度为 500 的 ViewBox 相同。因此,要获得所需的换行效果,只需微调 TextBlock 的宽度,直到看起来漂亮即可。

(显然,应该显示三行,但我不会重新上传)


好的,那个方法可行,但是我正在使用DataTemplate中的TextBlock,每个项目的文本都不同,所以我无法真正地“调整”文本框的宽度。 - Sun
当然可以。只需设置一个适合文本样本外观的宽度即可。Viewbox 将根据模板项容器的大小进行调整,而 TextBlock 将随着换行而缩放。我不知道你想要实现什么,但也许 Viewbox 是一个误导。把它拿掉试试看。 - Luke Puplett
1
嗯,那么viewbox的整个目的是什么呢?最初的意图是调整内容以适应不同的屏幕尺寸/分辨率。如果屏幕房地产是静态的,那么就没有必要使用viewboxes。因此,我认为设置宽度不是可行的解决方案。在较小的分辨率屏幕上,它会严重破坏演示效果。 - Matt
1
没错,那么你怎么知道视图框内的内容大小呢?大多数情况下你是不知道的。我认为假设 OP 使用了静态文本作为示例是非常安全的。 - Matt
我不明白。你需要通过视觉调整ViewBox中内容的大小,直到看起来合适为止。例如,我想让“This is the text that's”出现在第一行,所以我会调整TextBlock的宽度,直到它在那个位置换行。现在,即使整个ViewBox变得更大或更小,它始终看起来像那样;即使被拉伸到公交车上,它也始终会像那样换行。 - Luke Puplett
显示剩余2条评论

2
我遇到了同样的问题,我有很多按钮需要使用ViewBox来处理本地化。原因是Width被设置为Infinity,因为按钮或控件的宽度由父控件确定。幸运的是,控件有一个名为ActualWidth的属性。该属性保存了渲染宽度,我可以在绑定中使用它:
<Button>
    <Button.Content>
        <Viewbox StretchDirection="DownOnly">
            <TextBlock Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Button}}" TextWrapping="Wrap" TextAlignment="Center" Text="{Binding }" />
        </Viewbox>
    </Button.Content>
</Button>

因此,文本块的宽度与按钮的当前宽度相同。如果按钮的宽度发生更改,则会自动更新。根据给定的宽度,文本块将进行换行,而视口只有在必要时才会缩小(如果应用了StretchDirection="DownOnly")。

https://learn.microsoft.com/en-us/dotnet/api/system.windows.frameworkelement.actualwidth?view=netframework-4.8


0

您不必固定任何控件的宽度或最大宽度。使用虚拟网格并绑定到其ActualWidth即可。请参见代码https://github.com/omeraziz/NoTextOverflowWPF

<Window Title="NoTextOverflow"
    x:Class="NoTextOverflow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="Auto" Height="Auto"
    ResizeMode="CanResize" SizeToContent="WidthAndHeight">

<!--
    There is no fixed width in any of the UI elements including window, Label, TextBlock, TextBox etc.
    Window's SizeToContent grows and shrinks with the contents.
-->

<Grid Margin="10" ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Label VerticalAlignment="Center" Content="Type Here:" />
    <TextBox x:Name="LongText"
             Grid.Column="1" Grid.ColumnSpan="2"
             Width="{Binding ElementName=WidthRestrictorGrid, Path=ActualWidth, Mode=OneWay}"
             MinWidth="100"
             Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center"
             Text="Type here a long message and resize this window" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" />

    <!--
        This grid is used to calculate width of middle two columns.
        Remove this and its references to see the effect without this grid.
        Since this is not parent of TextBox and TextBlock so it must have a Name to bind with its Actualwidth
    -->

    <Grid x:Name="WidthRestrictorGrid"
          Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"
          Margin="10,1" HorizontalAlignment="Stretch" />

    <TextBlock Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
               Width="{Binding ElementName=WidthRestrictorGrid, Path=ActualWidth, Mode=OneWay}"
               MinWidth="50"
               Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top"
               Background="LightGray"
               Text="{Binding ElementName=LongText, Path=Text}"
               TextWrapping="Wrap" />

    <Button Grid.Row="2" Grid.Column="3"
            Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom"
            Content="Dummy" />

</Grid>

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