我有这样的标签:
<Grid Name="grid_footer" Grid.Row="2" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="3.4*" />
<RowDefinition Name="row_text" Height="3.2*" />
<RowDefinition Height="3.4*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.38*" />
<ColumnDefinition Width="9.62*" />
</Grid.ColumnDefinitions>
<!-- project location label -->
<Label Name ="FileLocationLabel" Content="TEST" Foreground="Black" Background="Beige" FontWeight="Bold" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="1" HorizontalAlignment="Left" Padding="0" FontSize="{Binding ElementName=row_text, Path=ActualHeight}"/>
</Grid>
正如你所看到的,底部仍然有一些不需要的填充物,我已经尝试了几乎所有东西来移除它但我不能。我只想让字体从行的顶部延伸到底部。
答案 0 :(得分:2)
首先,请尝试以下方法:
ActualHeight
,因为这不是来自RowDefinition
TextBlock.LineHeight
和TextBlock.LineStackingStrategy
设置添加到标签中(从https://stackoverflow.com/a/7568216/5265292中获取)FontFamily="Arial"
时,我得到的间距细节与默认字体不同。
<Border
x:Name="container1"
Grid.Row="1" Grid.Column="1"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Padding="0" Margin="0" BorderThickness="0">
<Label
Name ="FileLocationLabel"
Content="TESTg"
Foreground="Black" Background="Beige"
FontWeight="Bold"
HorizontalAlignment="Left"
Padding="0" Margin="0"
TextBlock.LineHeight="{Binding ElementName=container1,Path=ActualHeight}"
TextBlock.LineStackingStrategy="BlockLineHeight"
FontSize="{Binding ElementName=container1,Path=ActualHeight}"/>
</Border>
如果您需要更精确的字体大小调整,可能需要计算特定字体设置的实际文字大小,类似于此答案https://stackoverflow.com/a/15982149/5265292
注意我在测试内容中添加了"g"
,因为它使用了文本空间的下半部分,而"TEST"
我决定仔细研究一下这个问题,并提出以下转换器来确定字体大小和lineheight,以支持不同的文本和字体。
/// <summary>
/// Values:
/// - text to be rendered
/// - available height
/// - framework element with values for fontfamily etc
///
/// By default, returns a font size for a given text to fit into available height
/// With parameter = "lineheight", produces the lineheight for a given text and font size
/// </summary>
public class FontSizeProvider : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
string text = values[0] as string;
double height = System.Convert.ToDouble(values[1]);
FrameworkElement f = values[2] as FrameworkElement;
if (height <= 0.0)
{
height = 10;
}
var param = parameter as string;
// (1) in order to compute the LineHeight, take the font size, produce formatted text
// and determine the LineHeight based on available space and the size of text below the baseline
// (2) in order to compute the fontsize, take the container height, produce formatted text
// and scale the font depending on the actual text size
double fsize = param == "lineheight" ? TextBlock.GetFontSize(f) : height;
FontFamily family = TextBlock.GetFontFamily(f);
FontStyle style = TextBlock.GetFontStyle(f);
FontWeight weight = TextBlock.GetFontWeight(f);
FontStretch stretch = TextBlock.GetFontStretch(f);
// produce the formatted text
var formattedText = new FormattedText(text, culture,
f.FlowDirection,
new Typeface(family, style, weight, stretch),
fsize, Brushes.Black);
// get the result
if (param == "lineheight")
{
var afterBaseline = formattedText.Height - formattedText.Baseline + formattedText.OverhangAfter;
// for some reason, the desired line height needs to be scaled according to the font family line sizes
var scalingFactor = family.LineSpacing / family.Baseline;
var lineHeightResult = (height - afterBaseline) * scalingFactor;
return System.Convert.ChangeType(lineHeightResult, targetType);
}
else
{
var fontSizeResult = height * height / formattedText.Extent;
return System.Convert.ChangeType(fontSizeResult, targetType);
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
资源实例:
<local:FontSizeProvider x:Key="fontSizeProvider"/>
用法:
<Border x:Name="container1"
Grid.Row="1" Grid.Column="1"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Padding="0" Margin="0" BorderThickness="0">
<Label
Content="TÉ"
Foreground="Black" Background="Beige"
HorizontalAlignment="Left"
Padding="0" Margin="0"
TextBlock.LineStackingStrategy="BlockLineHeight">
<Label.FontSize>
<MultiBinding Converter="{StaticResource fontSizeProvider}">
<Binding RelativeSource="{RelativeSource Self}" Path="Content"/>
<Binding ElementName="container1" Path="ActualHeight"/>
<Binding RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Label.FontSize>
<TextBlock.LineHeight>
<MultiBinding Converter="{StaticResource fontSizeProvider}" ConverterParameter="lineheight">
<Binding RelativeSource="{RelativeSource Self}" Path="Content"/>
<Binding ElementName="container1" Path="ActualHeight"/>
<Binding RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</TextBlock.LineHeight>
</Label>
</Border>
缩放字体大小,以便将实际文本与实际字体放大以填充容器的高度。这意味着,对于相同的容器高度,文本"Ég"
(较小的字体,因为文本使用很多高度)和"ace"
(较大的字体,因为所有字母都是较小的高度)之间的字体大小会有所不同。
在计算LineHeight
时我遇到了一个奇怪的问题:我不得不将可用高度乘以1.22
(对于Segoe UI字体),以使文本的基线出现在底部可用空间。这对其他一些字体并不适用。经过一些测试后,我发现每个字体的正确比例因子由fontfamily.LineSpacing / fontfamily.Baseline
给出。
解决了缩放因子问题后,该方法非常简单:计算在基线下方渲染的文本高度,并根据文本高度减去下面的额外空间来调整线高度。
答案 1 :(得分:0)
将VerticalAlignment
属性设置为Top
:
<Label Name ="FileLocationLabel" ... VerticalAlignment="Top" />
答案 2 :(得分:-1)
尝试使用ViewBox
来展开Label
<Viewbox Grid.Row="1" Grid.Column="1" StretchDirection="Both" Stretch="Uniform" HorizontalAlignment="Left">
<Label Name ="FileLocationLabel" Content="TEST"
Foreground="Black" Background="Beige" FontWeight="Bold"
HorizontalAlignment="Left" VerticalAlignment="Stretch" Padding="0"/>
</Viewbox>