【发布时间】:2013-03-16 12:12:00
【问题描述】:
我在一个网格中的 WPF 中有几个 TextBlock,我想根据它们的可用宽度/高度进行缩放。当我搜索自动缩放字体大小时,典型的建议是将 TextBlock 放入 ViewBox。
所以我这样做了:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox MaxHeight="18" Grid.Column="0" Stretch="Uniform" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock Text="{Binding Text1}" />
</Viewbox>
<Viewbox MaxHeight="18" Grid.Column="1" Stretch="Uniform" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock Text="{Binding Text2}" />
</Viewbox>
<Viewbox MaxHeight="18" Grid.Column="2" Stretch="Uniform" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock Text="{Binding Text3}" />
</Viewbox>
</Grid>
它会自动缩放每个 TextBlock 的字体。然而,这看起来很有趣,因为如果其中一个 TextBlocks 有更长的文本,那么它的字体会更小,而它的相邻网格元素会使用更大的字体。我希望字体大小按组缩放,如果我可以为一组控件指定“SharedSizeGroup”以自动调整其字体大小,那可能会很好。
例如
第一个文本块文本可能是“3/26/2013 10:45:30 AM”,第二个 TextBlocks 文本可能是“FileName.ext”。如果这些跨越窗口的宽度,并且用户开始调整窗口的大小越来越小。日期将开始使其字体小于文件名,具体取决于文件名的长度。
理想情况下,一旦某个文本字段开始调整字体点大小,它们就会全部匹配。有没有人想出一个解决方案,或者可以给我一个镜头,看看你将如何使它工作?如果它需要自定义代码,那么希望我们/我可以将它重新打包成自定义的混合或附加行为,以便将来可重用。我认为这是一个非常普遍的问题,但我无法通过搜索找到任何内容。
更新 我尝试了 Mathieu 的建议,它有点工作,但它有一些副作用:
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="270" Width="522">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Fill="SkyBlue" />
<Viewbox Grid.Row="1" MaxHeight="30" Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="SomeLongText" Margin="5" />
<TextBlock Grid.Column="1" Text="TextA" Margin="5" />
<TextBlock Grid.Column="2" Text="TextB" Margin="5" />
</Grid>
</Viewbox>
</Grid>
</Window>
老实说,缺少 hte 比例列对我来说可能没问题。我不介意自动调整列大小以巧妙利用空间,但它必须跨越窗口的整个宽度。
注意没有 maxsize,在这个扩展示例中,文本太大了:
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="270" Width="522">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Fill="SkyBlue" />
<Viewbox Grid.Row="1" Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="col"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="SomeLongText" Margin="5" />
<TextBlock Grid.Column="1" Text="TextA" Margin="5" />
<TextBlock Grid.Column="2" Text="TextB" Margin="5" />
</Grid>
</Viewbox>
</Grid>
在这里,我想限制字体的大小,这样就不会浪费垂直窗口的空间。 我希望输出左、中、右对齐,字体尽可能大,达到所需的最大尺寸。
@adabyron
您提出的解决方案还不错(而且是最好的),但它确实有一些限制。例如,最初我希望我的列是成比例的(第二个应该居中)。例如,我的 TextBlocks 可能会标记图表的起点、中心和终点,其中对齐很重要。
<Window x:Class="WpfApplication6.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:b="clr-namespace:WpfApplication6.Behavior"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Fill="SkyBlue" />
<Line X1="0.5" X2="0.5" Y1="0" Y2="1" Stretch="Fill" StrokeThickness="3" Stroke="Red" />
<Grid Grid.Row="1">
<i:Interaction.Behaviors>
<b:MoveToViewboxBehavior />
</i:Interaction.Behaviors>
<Viewbox Stretch="Uniform" />
<ContentPresenter >
<ContentPresenter.Content>
<Grid x:Name="TextBlockContainer">
<Grid.Resources>
<Style TargetType="TextBlock" >
<Setter Property="FontSize" Value="16" />
<Setter Property="Margin" Value="5" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="SomeLongText" VerticalAlignment="Center" HorizontalAlignment="Center" />
<TextBlock Grid.Column="2" Text="TextA" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Grid.Column="4" Text="TextB" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</Grid>
</Window>
结果如下。请注意,它不知道它会在早期被剪裁,然后当它替换 ViewBox 时,它看起来好像 Grid 默认为列大小“自动”并且不再对齐中心。
【问题讨论】:
-
我不确定我是否仍然知道问题所在。您实施了下面的解决方案并获得了问题中的最后一个屏幕截图,对吗?您能否发布另一个屏幕截图,其中出现您现在尝试避免的情况?我只是无法想象? =)
-
@Akku 该解决方案应该看起来像第一个屏幕截图,但没有左/右浪费的边距。文本块的字体大小应相同,但左侧、中心和右侧对齐。这有意义吗?我想创建一个“组”控件,如果由于空间有限而必须将它们调整为更小,那么它们都选择相同的大小但字体更小。
-
那么左边的词应该多在左边,右边的词应该多在右边吗?或者文本是否应该被拉伸以看起来有点尴尬? :-)
-
@Akku 是的,我绝对不希望字体拉伸不成比例。我只想要 3 个等距的列,第一个文本左对齐,第二个文本居中对齐,第三个文本右对齐。例如假设 FontSize 为 18,但网格变得太短或太薄而无法显示文本,文本将变为较小的字体大小以使其适合。每个文本框应该是相同大小的字体。它应该不看起来像一种字体是 8pt 而另一种字体是 16pt。还应保持间距,使其看起来不像是居中的自动调整大小的网格,但具有较大的边距 L&R。