Il n'y a pas XAML seule solution, vous devez utiliser le code derrière. En outre, même avec le code-behind, il n'y a pas de solution générale pour cela, parce que si votre texte est multi-ligne? Quelle ligne de base devrait être utilisée dans ce cas? Ou s'il y a plusieurs éléments de texte dans votre modèle? Comme un en-tête et un contenu, ou plus, quelle ligne de base alors? En bref, le mieux est d'aligner le texte manuellement en utilisant les marges supérieure/inférieure. Si vous êtes prêt à faire l'hypothèse que vous avez un seul élément de texte, vous pouvez déterminer la distance en pixels de la ligne de base depuis le haut de l'élément en instanciant un objet FormattedText
avec toutes les mêmes propriétés que l'élément existant élément de texte. L'objet FormattedText
a une propriété double
Baseline
qui contient cette valeur. Notez que vous devez toujours entrer manuellement une marge, car l'élément peut ne pas être placé exactement en haut ou en bas de son conteneur.
Voir ce post forum MSDN: Textbox Baseline
Voici une méthode que j'ai écrit qui extrait cette valeur. Il utilise la réflexion pour obtenir les propriétés pertinentes car elles ne sont communes à aucune classe de base unique (elles sont définies séparément sur Control
, TextBlock
, Page
, TextElement
et peut-être d'autres).
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, en réponse à votre commentaire, je ne crois pas que vous avez réellement essayé cette solution, parce que cela fonctionne.Voici un exemple:
Voici le 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>
Et voici le code derrière qui permet d'atteindre ce
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);
ah haa! Votre mise à jour clarifie le problème. –