Не существует единственного решения XAML, вам нужно использовать код. Кроме того, даже с выделенным кодом для этого нет общего решения, потому что что, если ваш текст многострочный? Какую базовую линию следует использовать в этом случае? Или что, если в вашем шаблоне несколько текстовых элементов? Например, заголовок и контент или что-то еще, какая тогда базовая линия?
Короче говоря, лучше всего выровнять текст вручную, используя верхнее / нижнее поля.
Если вы готовы сделать предположение, что у вас есть единственный текстовый элемент, вы можете определить расстояние в пикселях от базовой линии от верха элемента, создав экземпляр объекта FormattedText
со всеми теми же свойствами существующего текстового элемента. У объекта FormattedText
есть свойство double
Baseline
, которое содержит это значение. Обратите внимание, что вам все равно придется вручную вводить поля, потому что элемент может не располагаться точно напротив верха или низа своего контейнера.
См. Это сообщение на форуме MSDN: Textbox Baseline < / а>
Вот метод, который я написал, который извлекает это значение. Он использует отражение для получения соответствующих свойств, поскольку они не являются общими для какого-либо отдельного базового класса (они определяются отдельно для 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;
}
РЕДАКТИРОВАТЬ: Шимми, в ответ на ваш комментарий, я не верю, что вы действительно пробовали это решение, потому что оно работает. Вот пример:
Вот XAML:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0,40,0,0"/>
</Style>
</StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<TextBlock Name="tb1" Text="Lorem " FontSize="10"/>
<TextBlock Name="tbref" Text="ipsum"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Name="tb2" Text="dolor " FontSize="20"/>
<TextBlock Text="sit"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Name="tb3" Text="amet " FontSize="30"/>
<TextBlock Text="consectetuer"/>
</StackPanel>
</StackPanel>
И вот код, который обеспечивает это
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);
person
Aviad P.
schedule
10.01.2010