在不涉及测量字符串和计算边距、填充等值转换器的情况下,其中一个更简单的解决方案是创建一个隐藏(而非折叠)的TextBlock
,该TextBlock
只有你想要的行数,并将其ActualHeight
绑定到可见TextBlock
的MaxHeight
。用作测量的不可见TextBlock
必须将其Visibility
设置为Hidden
,以便即使它不显示(Collapsed
会导致其完全消失),它仍然是布局计算的一部分。
以下是一个演示,你可以将其放入新项目中以查看其工作原理(我使用4行以使滚动条更容易使用)。
这部分替换了Window
内部的默认Grid
:
<Grid TextElement.FontSize="12">
<TextBlock Name="limiter"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="100"
Visibility="Hidden"
Background="Gray">
</TextBlock>
<ScrollViewer MaxHeight="{Binding ElementName=limiter, Path=ActualHeight}"
Margin="40,0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
Background="LightGray"
VerticalScrollBarVisibility="Auto">
<TextBlock Name="vis" />
</ScrollViewer>
<Button Name="AddLine"
Padding="8"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Click="AddLine_Click">Add A Line</Button>
</Grid>
在
Window
的构造函数中,我向隐藏的
TextBlock
添加了任意行数的内容(你也可以在XAML中使用
Run
和
LineBreak
元素):
var limitString = "AgjZ";
limitString = limitString + Environment.NewLine + limitString + Environment.NewLine + limitString + Environment.NewLine + limitString;
limiter.Text = limitString;
Button
的AddLine_Click
处理程序如下,这样您就可以看到不同行数的效果:
private int counter = 0;
private void AddLine_Click( object sender, RoutedEventArgs e ) {
var newline = string.Empty;
if ( !string.IsNullOrWhiteSpace( vis.Text ) )
newline = Environment.NewLine;
vis.Text += string.Format( newline + "This is line #{0}.", ++counter );
}
记住,隐藏的 TextBlock
需要在与你想显示的那个相同的范围内,以便继承 FontSize
和其他与字体相关的值。如果在可见的 TextBlock
或 ScrollViewer
上设置了任何内容,也需要在隐藏的 TextBlock
上进行设置。你还可以使用绑定确保隐藏的 TextBlock
与可见的那个具有相同的样式。