The following snippet:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<Label Content="Name:"/>
<Label Content="Itzhak Perlman" FontSize="44"/>
</StackPanel>
</Grid>
</Window>
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.
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?
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.
Thanks
I actually found a simple answer based on Aviad's.
I created a converter that contains Aviad's function that accepts the element itself and returns calculated Thickness.
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.
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?
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. TheFormattedText
object has adouble
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.See this MSDN forum post: 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).EDIT: Shimmy, in response to your comment, I don't believe you've actually tried this solution, because it works. Here's an example:
Here's the XAML:
And here's the code behind that achieves this
This should works well. Experiment with Baseline/Bottom/Center/Top.
XAML designer supports aligning
TextBlock
controls by baseline at design time:This assigns fixed margins to your controls. As long as font sizes do not change at run time, the alignment will be preserved.
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:
The only thing that is missing from the Run element is databinding of the Text property but that might be added sooner or later.
A Run will not fix the alignment of labels and their textboxes but for many simple situation the Run will do quite nicely.
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/
2) Use the LineHeight and LineStackingStrategy = BlockLineHeight for your TextBlock style. This will align the two at their baseline easily.