The following snippet:
以下片段:
Renders the following:
呈现以下内容:
Is there any way I can set in the Labels' styles so that their text bottoms should be aligned?
I have the same question with TextBlocks as well.
有没有什么方法可以设置标签的样式,以便他们的文本底部应该对齐?我对TextBlocks也有同样的问题。
NOTE: since I've been struggling with this issue for a while, please post only certains answers that you know that work.
I already tried: VerticalAlignment, VerticalContentAlignment, Padding, Margin. Is there anything else I am not aware of?
注意:由于我一直在努力解决这个问题,请发布您知道可行的某些答案。我已经尝试过:VerticalAlignment,VerticalContentAlignment,Padding,Margin。还有什么我不知道的吗?
I've read this post, but it doesn't talk about a scenario of different font size.
我已经阅读了这篇文章,但它没有谈到不同字体大小的情况。
UPDATE: The problem is, that even Padding is set to 0 there is still an indeterminate space around the font, within the ContentPresenter area. this space varies on the font size. If I could control this space I would be in a better situation.
更新:问题是,即使Padding设置为0,在ContentPresenter区域内的字体周围仍然存在不确定的空间。这个空间因字体大小而异。如果我可以控制这个空间,我会处于更好的状态。
Thanks
谢谢
6
There is no XAML only solution, you have to use code behind. Also, even with code-behind, there's no general solution for this, because what if your text is multi-line? Which baseline should be used in that case? Or what if there are multiple text elements in your template? Such as a header and a content, or more, which baseline then?
没有XAML唯一的解决方案,您必须使用后面的代码。此外,即使使用代码隐藏,也没有通用的解决方案,因为如果你的文字是多行的呢?在这种情况下应该使用哪个基线?或者,如果模板中有多个文本元素,该怎么办?如标题和内容,或更多,哪个基线呢?
In short, your best bet is to align the text manually using top/bottom margins.
简而言之,您最好的选择是使用上/下边距手动对齐文本。
If you're willing to make the assumption that you have a single text element, you can figure out the pixel distance of the baseline from the top of the element by instantiating a FormattedText
object with all the same properties of the existing text element. The FormattedText
object has a double
Baseline
property which holds that value. Note that you still would have to manually enter a margin, because the element might not sit exactly against the top or bottom of its container.
如果您愿意假设您有一个文本元素,则可以通过实例化具有现有文本元素的所有相同属性的FormattedText对象来计算基线与元素顶部的像素距离。 FormattedText对象具有双Baseline属性,该属性保存该值。请注意,您仍然必须手动输入边距,因为该元素可能不会完全位于其容器的顶部或底部。
See this MSDN forum post: Textbox Baseline
看到这篇MSDN论坛帖子:Textbox Baseline
Here's a method I wrote that extracts that value. It uses reflection to get the relevant properties because they are not common to any single base class (they are defined separately on Control
, TextBlock
, Page
, TextElement
and maybe others).
这是我写的一个提取该值的方法。它使用反射来获取相关属性,因为它们不是任何单个基类共有的(它们在Control,TextBlock,Page,TextElement和其他基础上分别定义)。
public double CalculateBaseline(object textObject)
{
double r = double.NaN;
if (textObject == null) return r;
Type t = textObject.GetType();
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
var fOntSizeFI= t.GetProperty("FontSize", bindingFlags);
if (fOntSizeFI== null) return r;
var fOntFamilyFI= t.GetProperty("FontFamily", bindingFlags);
var fOntStyleFI= t.GetProperty("FontStyle", bindingFlags);
var fOntWeightFI= t.GetProperty("FontWeight", bindingFlags);
var fOntStretchFI= t.GetProperty("FontStretch", bindingFlags);
var fOntSize= (double)fontSizeFI.GetValue(textObject, null);
var fOntFamily= (FontFamily)fontFamilyFI.GetValue(textObject, null);
var fOntStyle= (FontStyle)fontStyleFI.GetValue(textObject, null);
var fOntWeight= (FontWeight)fontWeightFI.GetValue(textObject, null);
var fOntStretch= (FontStretch)fontStretchFI.GetValue(textObject, null);
var typeFace = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
var formattedText = new FormattedText(
"W",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeFace,
fontSize,
Brushes.Black);
r = formattedText.Baseline;
return r;
}
EDIT: Shimmy, in response to your comment, I don't believe you've actually tried this solution, because it works. Here's an example:
编辑:Shimmy,回应你的评论,我不相信你真的尝试过这个解决方案,因为它有效。这是一个例子:
Here's the XAML:
这是XAML:
And here's the code behind that achieves this
这是实现这一目标的背后代码
double baseRef = CalculateBaseline(tbref);
double base1 = CalculateBaseline(tb1) - baseRef;
double base2 = CalculateBaseline(tb2) - baseRef;
double base3 = CalculateBaseline(tb3) - baseRef;
tb1.Margin = new Thickness(0, 40 - base1, 0, 0);
tb2.Margin = new Thickness(0, 40 - base2, 0, 0);
tb3.Margin = new Thickness(0, 40 - base3, 0, 0);
23
Another fairly simple solution:
另一个相当简单的解
1) Use TextBlock controls instead of Labels. The reason being that TextBlock is lighter weight than Label - see http://joshsmithonwpf.wordpress.com/2007/07/04/differences-between-label-and-textblock/
1)使用TextBlock控件而不是标签。原因是TextBlock比Label更轻 - 请参阅http://joshsmithonwpf.wordpress.com/2007/07/04/differences-between-label-and-textblock/
2) Use the LineHeight and LineStackingStrategy = BlockLineHeight for your TextBlock style. This will align the two at their baseline easily.
2)使用LineHeight和LineStackingStrategy = BlockLineHeight作为TextBlock样式。这将使两者在基线处轻松对齐。
5
I really like the creative solutions that are presented here but I do think that in the long run (pun intended) we should use this:
我真的很喜欢这里展示的创意解决方案,但我认为从长远来看(双关语)我们应该使用这个:
What
ever
FontSize
The only thing that is missing from the Run element is databinding of the Text property but that might be added sooner or later.
Run元素中唯一缺少的是Text属性的数据绑定,但可能迟早会添加。
A Run will not fix the alignment of labels and their textboxes but for many simple situation the Run will do quite nicely.
Run不会修复标签及其文本框的对齐方式,但对于许多简单的情况,Run会做得很好。
2
Small
Big
This should works well. Experiment with Baseline/Bottom/Center/Top.
这应该很好。使用Baseline / Bottom / Center / Top进行实验。
1
XAML designer supports aligning TextBlock
controls by baseline at design time:
XAML设计器支持在设计时按基线对齐TextBlock控件:
This assigns fixed margins to your controls. As long as font sizes do not change at run time, the alignment will be preserved.
这会为您的控件分配固定边距。只要字体大小在运行时不会更改,就会保留对齐方式。
0
I actually found a simple answer based on Aviad's.
我实际上找到了一个基于Aviad的简单答案。
I created a converter that contains Aviad's function that accepts the element itself and returns calculated Thickness.
我创建了一个包含Aviad函数的转换器,该函数接受元素本身并返回计算的厚度。
Then I set up
然后我成立了
The disadvantage is that this is obviously occupies the original Margin property, since a TextBlock doesn't have a template so we can't set it via TemplateBinding.
缺点是这显然占用了原始Margin属性,因为TextBlock没有模板,所以我们无法通过TemplateBinding设置它。