Alignement vertical du texte dans WPF TextBlock


228

Comment attribuer un alignement central vertical au texte à l'intérieur d'un TextBlock? J'ai trouvé la propriété TextAlignment mais c'est pour l'alignement horizontal du texte. Comment le faire pour l'alignement vertical du texte?


@shr et autres: notez que cela TextAlignmentn'affecte que l'alignement horizontal, pas l' alignement vertical (comme la question fait référence).
Drew Noakes du

Réponses:


284

Un bloc de texte lui-même ne peut pas faire d'alignement vertical

La meilleure façon de le faire que j'ai trouvée est de mettre le bloc de texte à l'intérieur d'une bordure, afin que la bordure fasse l'alignement pour vous.

<Border BorderBrush="{x:Null}" Height="50">
    <TextBlock TextWrapping="Wrap" Text="Some Text" VerticalAlignment="Center"/>
</Border>

Remarque: Ceci est fonctionnellement équivalent à l'utilisation d'une grille, cela dépend simplement de la façon dont vous souhaitez que les contrôles s'intègrent avec le reste de votre mise en page pour savoir lequel est le plus approprié


22
+1 La hauteur de la bordure doit être définie pour que l'alignement vertical prenne effet.
Tim Lloyd

21
En outre, le TextBlock ne peut pas avoir une hauteur spécifiée, ou il ne sera pas centré verticalement.
pearcewg

20
@gav - TextAlignment ne fait que l'alignement horizontal ... la question concerne l'alignement vertical
Orion Edwards

@TimLloyd - Je ne suis pas sûr que ce soit toujours vrai. J'ai cette configuration, la bordure a la hauteur "Auto" et ça marche bien. Il est dans une cellule de grille avec des hauteurs de ligne étoilées (et d'autres choses dans la ligne).
Bob Sammers

97

Bien que Orion Edwards Answer fonctionne pour n'importe quelle situation, il peut être difficile d'ajouter la bordure et de définir les propriétés de la bordure à chaque fois que vous voulez faire cela. Un autre moyen rapide consiste à définir le remplissage du bloc de texte:

<TextBlock Height="22" Padding="3" />

11
je pense que c'est la réponse la plus brillante.
Boppity Bop

1
Cela ne fonctionne que si la police a une taille de 16 pixels, n'est-ce pas?
C4d

1
La réponse acceptée alignera correctement verticalement les bordures réelles de la TextBox, mais elle ne semble pas avoir d'effet sur le texte réel à l'intérieur ... ce qui est à peu près sûr que l'intention de l'OP. Cette solution fonctionne à la place d'une propriété TextVerticalAlignment appropriée et obtient mon vote positif. :)
Trekkie

Qu'en est-il du contenu dynamique dans le bloc, 2 ou 5 lignes ne nécessiteraient-elles pas un remplissage différent, également des polices 10pt vs 24pt
Reahreic

57

Le TextBlock ne prend pas en charge l'alignement vertical du texte.

Je contourne cela en enveloppant le bloc de texte avec une grille et en définissant HorizontalAlignment = "Stretch" et VerticalAlignment = "Center".

Comme ça:

<Grid>
    <TextBlock 
        HorizontalAlignment="Stretch"
        VerticalAlignment="Center"
        Text="Your text" />
</Grid>

+1 N'a même pas besoin de définir la hauteur de la grille, comme avec l'approche basée sur la bordure.
Efran Cobisi

J'ai trouvé que cette approche me convenait le mieux. Je crée des lumières indicateur de dynamique en superposant TextBlockà l' Ellipseintérieur d' un Grid. Pas besoin de lier mes propriétés de largeur et de hauteur ou de faire quelque chose de délicat.
paddy

17

Vous pouvez utiliser une étiquette au lieu d'un bloc de texte.

<Label Content="Hello, World!">
    <Label.LayoutTransform>
        <RotateTransform Angle="270"/>
    </Label.LayoutTransform>
</Label>

3
Bien, le Label a VerticalContentAlignment. Greeeat. +1
Ignacio Soler Garcia

3
Pas clair si l'OP devait utiliser un TextBlock ou pouvait s'en tirer avec une étiquette. L'utilisation d'une étiquette a fonctionné pour ce dont j'avais besoin. +1
Steve Kalemkiewicz

19
Cela répond à la question de savoir comment produire du texte vertical, pas comment appliquer l'alignement vertical!
Sebastian Negraszus

26
Cette question est en cours de discussion sur meta: meta.stackoverflow.com/questions/305572/…
NathanOliver

6

Si vous pouvez vous passer de l' habillage du texte , je pense que remplacer le TextBlock par une étiquette est la façon la plus succincte de le faire. Sinon, suivez l'une des autres réponses valides.

<Label Content="Some Text" VerticalAlignment="Center"/>

6

TextBlockne prend pas en charge l'alignement vertical de son contenu. Si vous devez utiliserTextBlock vous devez l'aligner par rapport à son parent.

Cependant, si vous pouvez utiliser à la Labelplace (et ils ont des fonctionnalités très similaires), vous pouvez positionner le contenu du texte:

<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
   I am centred text!
</Label>

Le Labelva s'étirer pour remplir ses limites par défaut, ce qui signifie que le texte de l'étiquette sera centré.


3

Pour moi, VerticalAlignment="Center"résout ce problème.
Cela peut être dû au fait que le TextBlockest enveloppé dans une grille, mais il en va de même pour pratiquement tout dans wpf.


1

J'ai trouvé que modifier le style de la zone de texte (c'est-à-dire:) controltemplatepuis modifier l' PART_ContentHostalignement vertical sur Centre fera l'affaire


OP pose des questions sur TextBlocks. Ils n'ont pas de ControlTemplates.
ANeves

1

Juste pour rire, donnez à ce XAML un tourbillon. Ce n'est pas parfait car ce n'est pas un «alignement» mais il vous permet d'ajuster l'alignement du texte dans un paragraphe.

<TextBlock>
    <TextBlock BaselineOffset="30">One</TextBlock>
    <TextBlock BaselineOffset="20">Two</TextBlock>  
    <Run>Three</Run>            
    <Run BaselineAlignment="Subscript">Four</Run>   
</TextBlock>

1

Si vous pouvez ignorer la hauteur de TextBlock, il est préférable d'utiliser ceci:

<TextBlock Height="{Binding}" Text="Your text"
TextWrapping="Wrap" VerticalAlignment="Center" Width="28"/>

1

Dans mon cas, j'ai fait cela pour rendre l' TextBlockaffichage plus agréable.

<Border BorderThickness="3" BorderBrush="Yellow" CornerRadius="10" Padding="2"
    HorizontalAlignment="Center" VerticalAlignment="Center" Height="30" Width="150">
        <TextBlock FontSize="20" Height="23" HorizontalAlignment="Left" Margin="0,0,0,-5" Text="" VerticalAlignment="Top" Width="141" Background="White" />
</Border>

L'astuce pour rendre le texte plus bas est de définir

Margin="0,0,0,-5"


0

J'ai trouvé que je devais le faire légèrement différent. Mon problème était que si je modifiais la taille de la police, le texte se déplacerait vers le haut dans la TextBox au lieu de rester en bas avec le reste des TextBox sur la ligne. En changeant l'alignement vert de haut en bas, j'ai pu changer la police par programme de la taille 20 à la taille 14 et arrière, en gardant la gravité du texte en bas et en gardant les choses propres. Voici comment:

entrez la description de l'image ici


0

TextBox à ligne unique aligné verticalement.

Pour développer la réponse fournie par @Orion Edwards, voici comment vous feriez complètement à partir de code-behind (aucun style défini). Fondamentalement, créez une classe personnalisée qui hérite de Border dont le Child est défini sur TextBox. L'exemple ci-dessous suppose que vous ne voulez qu'une seule ligne et que la bordure est un enfant d'un canevas. Suppose également que vous auriez besoin d'ajuster la propriété MaxLength de TextBox en fonction de la largeur de la bordure. L'exemple ci-dessous définit également le curseur de la bordure pour imiter une zone de texte en le définissant sur le type «IBeam». Une marge de «3» est définie de sorte que le TextBox n'est pas absolument aligné à gauche de la bordure.

double __dX = 20;
double __dY = 180;
double __dW = 500;
double __dH = 40;
int __iMaxLen = 100;

this.m_Z3r0_TextBox_Description = new CZ3r0_TextBox(__dX, __dY, __dW, __dH, __iMaxLen, TextAlignment.Left);
this.Children.Add(this.m_Z3r0_TextBox_Description);

Classe:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;


namespace ifn0tz3r0Exp
{
    class CZ3r0_TextBox : Border
    {
        private TextBox m_TextBox;

        private SolidColorBrush m_Brush_Green = new SolidColorBrush(Colors.MediumSpringGreen);
        private SolidColorBrush m_Brush_Black = new SolidColorBrush(Colors.Black);
        private SolidColorBrush m_Brush_Transparent = new SolidColorBrush(Colors.Transparent);

        public CZ3r0_TextBox(double _dX, double _dY, double _dW, double _dH, int _iMaxLen, TextAlignment _Align)
        {

            /////////////////////////////////////////////////////////////
            //TEXTBOX
            this.m_TextBox = new TextBox();
            this.m_TextBox.Text = "This is a vertically centered one-line textbox embedded in a border...";
            Canvas.SetLeft(this, _dX);
            Canvas.SetTop(this, _dY);
            this.m_TextBox.FontFamily = new FontFamily("Consolas");
            this.m_TextBox.FontSize = 11;
            this.m_TextBox.Background = this.m_Brush_Black;
            this.m_TextBox.Foreground = this.m_Brush_Green;
            this.m_TextBox.BorderBrush = this.m_Brush_Transparent;
            this.m_TextBox.BorderThickness = new Thickness(0.0);
            this.m_TextBox.Width = _dW;
            this.m_TextBox.MaxLength = _iMaxLen;
            this.m_TextBox.TextAlignment = _Align;
            this.m_TextBox.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            this.m_TextBox.FocusVisualStyle = null;
            this.m_TextBox.Margin = new Thickness(3.0);
            this.m_TextBox.CaretBrush = this.m_Brush_Green;
            this.m_TextBox.SelectionBrush = this.m_Brush_Green;
            this.m_TextBox.SelectionOpacity = 0.3;

            this.m_TextBox.GotFocus += this.CZ3r0_TextBox_GotFocus;
            this.m_TextBox.LostFocus += this.CZ3r0_TextBox_LostFocus;
            /////////////////////////////////////////////////////////////
            //BORDER

            this.BorderBrush = this.m_Brush_Transparent;
            this.BorderThickness = new Thickness(1.0);
            this.Background = this.m_Brush_Black;            
            this.Height = _dH;
            this.Child = this.m_TextBox;
            this.FocusVisualStyle = null;
            this.MouseDown += this.CZ3r0_TextBox_MouseDown;
            this.Cursor = Cursors.IBeam;
            /////////////////////////////////////////////////////////////
        }
        private void CZ3r0_TextBox_MouseDown(object _Sender, MouseEventArgs e)
        {
            this.m_TextBox.Focus();
        }
        private void CZ3r0_TextBox_GotFocus(object _Sender, RoutedEventArgs e)
        {
            this.BorderBrush = this.m_Brush_Green;
        }
        private void CZ3r0_TextBox_LostFocus(object _Sender, RoutedEventArgs e)
        {
            this.BorderBrush = this.m_Brush_Transparent;
        }
    }
}

0

Je pense qu'il vaut mieux utiliser un Label (ou TextBlock) dans un Label, vous ne pouvez pas attacher un événement de souris directement dans le contrôle de bordure, enfin il est attaché dans le TextBlock, voici ma recommandation:

<Label 
    Height="32"
    VerticalContentAlignment="Center"
    HorizontalContentAlignment="Stretch"
    MouseLeftButtonUp="MenuItem_MouseLeftButtonUp">
    <TextBlock Padding="32 0 10 0">
        Label with click event
    </TextBlock>
</Label>

0

Je pense qu'il est sage d'utiliser une zone de texte sans bordure ni arrière-plan comme moyen facile et rapide d'atteindre un bloc de texte aligné au centre

<TextBox
TextWrapping="Wrap"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Background="{x:Null}"
BorderBrush="{x:Null}"
/>

-1
  <TextBox AcceptsReturn="True" 
           TextWrapping="Wrap"  
           VerticalContentAlignment="Top" >
  </TextBox>

1
La question était pour un TextBlocknon TextBox. -1
KnorxThieus
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.