Вертикальне вирівнювання тексту у текстовому блоці WPF


228

Як призначити вертикальне вирівнювання по центру тексту всередині TextBlock? Я знайшов властивість TextAlignment, але він призначений для горизонтального вирівнювання тексту. Як це зробити для вертикального вирівнювання тексту?


@shr та інші: зауважте, що TextAlignmentвпливає лише горизонтальне вирівнювання, а не вертикальне вирівнювання (як це стосується питання).
Дрю Ноакс

Відповіді:


284

Сам Textblock не може виконати вертикальне вирівнювання

Найкращий спосіб зробити це, що я знайшов, - помістити текстовий блок всередині межі, щоб межа була для вас вирівнюванням.

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

Примітка. Це функціонально еквівалентно використанню сітки, це просто залежить від того, як ви хочете, щоб елементи керування вписувалися в решту вашого макета щодо того, який із них підходить більше


22
+1 Для того, щоб набуло чинності вертикальне вирівнювання, потрібно встановити висоту рамки.
Тім Ллойд

21
Крім того, у TextBlock не може бути вказана висота або він не буде центрально вертикально.
pearcewg

20
@gav - TextAlignment виконує лише горизонтальне вирівнювання ... питання про вертикальне вирівнювання
Orion Edwards

@TimLloyd - Я не впевнений, що це завжди так. У мене це налаштування, бордюр має висоту "Авто", і він працює чудово. Він знаходиться в комірці сітки з висотою рядка зірочкою (та іншими речами підряд).
Боб Саммерс

97

Хоча відповідь Orion Edwards працює в будь-якій ситуації, може бути болючим додавати межу та встановлювати властивості межі кожного разу, коли ви хочете це зробити. Ще один швидкий спосіб - встановити прокладку текстового блоку:

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

11
Я думаю, що це найяскравіша відповідь.
Boppity Bop

1
Це працює лише в тому випадку, якщо шрифт має розмір 16 пікселів.
C4d

1
Прийнята відповідь буде правильно вертикально вирівнювати фактичні межі TextBox, але, схоже, це не вплине на фактичний текст у межах ... що, я впевнений, є наміром ОП. Це рішення працює замість належного властивості TextVerticalAlignment і отримує мою нагороду. :)
Trekkie

Що стосується динамічного контенту в блоці, не потрібно, щоб 2 або 5 рядків вимагали різного набивання, також шрифти 10pt vs 24pt
Reahreic

57

TextBlock не підтримує вертикальне вирівнювання тексту.

Я обіймаю це, обертаючи текстовий блок сіткою та встановлюючи HorizontalAlignment = "Stretch" та VerticalAlignment = "Центр".

Подобається це:

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

+1 Навіть не потрібно встановлювати висоту сітки, як при підході до кордону.
Ефран Кобісі

Я знайшов, що цей підхід для мене найкраще працює. Я створюю індикатор динамічного світла, накладаючи TextBlockна EllipseВсередині Grid. Не потрібно прив'язувати властивості моєї ширини та висоти чи робити щось складне.
рисовий

17

Ви можете використовувати мітку замість текстового блоку.

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

3
Приємно, що етикетка має VerticalContentAlignment. Greeeat. +1
Ігнасіо Солер Гарсія

3
Не зрозуміло, чи потрібно ОП використовувати TextBlock або може втекти з міткою. Використання мітки працювало на те, що мені потрібно. +1
Стів Калемкевич

19
Це відповідає на питання, як створити вертикальний текст, а не як застосувати вертикальне вирівнювання!
Себастьян Неграш

26
Це питання обговорюється на мета: meta.stackoverflow.com/questions/305572/…
NathanOliver

6

Якщо ви можете обійтися без обгортання тексту , я вважаю, що заміна TextBlock етикеткою - це найкоротший спосіб зробити це. В іншому випадку дотримуйтесь одну з інших дійсних відповідей.

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

6

TextBlockне підтримує вертикальне вирівнювання його вмісту. Якщо вам потрібно скористатися, TextBlockто вам доведеться вирівняти його стосовно батьків.

Однак якщо ви можете використовувати Labelнатомість (а вони мають дуже подібний функціонал), ви можете розмістити текстовий вміст:

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

LabelБуде розтягуватися , щоб заповнити свої кордони за замовчуванням, тобто текст лейбла буде центрирован.


3

Для мене VerticalAlignment="Center"вирішує цю проблему.
Це може бути тому, що TextBlockзагорнутий у сітку, але тоді практично все є у wpf.


1

Я виявив, що зміна стилю текстового поля (тобто:), controltemplateа потім зміна PART_ContentHostвертикального вирівнювання до центру виконають трюк


OP запитує про TextBlocks. Вони не мають ControlTemplates.
ANeves

1

Тільки для хихикань, дайте цьому XAML вихору. Це не ідеально, оскільки це не "вирівнювання", але дозволяє налаштувати вирівнювання тексту в абзаці.

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

1

Якщо ви можете не помітити висоту TextBlock, вам краще скористатися цим:

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

1

У моєму випадку я зробив це для того, щоб зробити TextBlockвигляд гарнішим.

<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>

Трюк зробити текст далі знизу - встановити

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


0

Я виявив, що мені це потрібно зробити трохи інакше. Моя проблема полягала в тому, що якби я змінив розмір шрифту, текст перемістився б в TextBox, а не залишився внизу, а решта TextBoxes - у рядку. Змінюючи вирівнювання вершини зверху вниз, я зміг програмно змінити шрифт від розміру 20 до розміру 14 і назад, зберігаючи гравітацію тексту внизу і підтримуючи акуратність. Ось як:

введіть тут опис зображення


0

Вертикально вирівняний єдиний рядок TextBox.

Щоб розширити відповідь, надану @Orion Edwards, саме так ви робите повністю з коду позаду (не встановлено жодних стилів). В основному створити користувацький клас, який успадковується від Border, який має свою дочірню програму TextBox. Наведений нижче приклад передбачає, що ви хочете лише одну лінію і що межа є полотниною полотна. Також передбачається, що вам потрібно буде відрегулювати властивість MaxLength TextBox на основі ширини кордону. Наведений нижче приклад також встановлює курсор Border для імітації Textbox, встановивши його на тип "IBeam". Поле "3" встановлюється так, щоб TextBox не був абсолютно вирівняний зліва від межі.

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);

Клас:

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

Я думаю, що краще використовувати мітку (або TextBlock) в мітку, ви не можете приєднати подію миші безпосередньо в контролі кордону, нарешті вона додається в TextBlock, це моя рекомендація:

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

0

Я думаю, що розумно використовувати текстове поле без меж і фону як простий і швидкий спосіб дістатися до текстового блоку, вирівняного по центру

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.