Выравнивание текста по вертикали в текстовом блоке WPF

StackOverflow https://stackoverflow.com/questions/1491649

Вопрос

Как мне назначить вертикальное выравнивание по центру текста внутри текстового блока?Я нашел свойство textAlignment, но оно предназначено для выравнивания текста по горизонтали.Как мне это сделать для выравнивания текста по вертикали?

Это было полезно?

Решение

Сам текстовый блок не может выполнять вертикальное выравнивание.

Лучший способ сделать это, который я нашел, — поместить текстовый блок внутри рамки, чтобы граница выполнила выравнивание за вас.

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

Примечание:Это функционально эквивалентно использованию сетки, просто зависит от того, как вы хотите, чтобы элементы управления вписывались в остальную часть вашего макета, и какой из них более подходит.

Другие советы

Пока Орион Эдвардс Ответ работает в любой ситуации, может быть сложно добавлять границу и устанавливать свойства границы каждый раз, когда вы хотите это сделать.Еще один быстрый способ — установить отступы текстового блока:

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

TextBlock не поддерживает вертикальное выравнивание текста.

Я обхожу эту проблему, обертывая текстовый блок сеткой и устанавливая HorizontalAlignment="Stretch" и UpperAlignment="Center".

Так:

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

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

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

Если можно обойтись без перенос текста, Я думаю, что замена TextBlock на Label — наиболее лаконичный способ сделать это.В противном случае следуйте одному из других действительных ответов.

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

TextBlock не поддерживает выравнивание содержимого по вертикали.Если вы должны использовать TextBlock затем вы должны выровнять его по отношению к родительскому элементу.

Однако, если вы можете использовать Label вместо этого (и они действительно обладают очень похожей функциональностью) вы может расположите текстовое содержимое:

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

Тот Самый Label по умолчанию будет растягиваться, заполняя свои границы, что означает, что текст метки будет располагаться по центру.

Для меня, VerticalAlignment="Center" исправляет эту проблему.
Это может быть потому, что TextBlockзавернут в сетку, но в wpf практически все так.

Я обнаружил, что изменение стиля текстового поля (т.е.: controltemplate), а затем изменив PART_ContentHost вертикальное выравнивание по центру поможет

Просто ради смеха попробуйте этот XAML.Он не идеален, поскольку не является «выравниванием», но позволяет регулировать выравнивание текста внутри абзаца.

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

Если вы можете не обращать внимания на высоту TextBlock, вам лучше использовать это:

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

В моем случае я сделал это, чтобы 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"

Вы можете увидеть мой пост в блоге.Вы можете установить произвольную высоту текстового блока из кода программной части.Для установки пользовательской высоты вам необходимо установить ее внутри рамки или панели стека.

http://ciintelligence.blogspot.com/2011/02/wpf-textblock-vertical-alignment-with.html

Я обнаружил, что мне нужно сделать это немного по-другому.Моя проблема заключалась в том, что если бы я изменил размер шрифта, текст в текстовом поле переместился бы вверх, а не остался бы внизу, а остальные текстовые поля находились бы в строке.Изменив вертикальное выравнивание сверху вниз, я смог программно изменить размер шрифта с размера 20 на размер 14 и обратно, сохраняя гравитацию текста внизу и сохраняя порядок.Вот как:

enter image description here

Vertically aligned single line TextBox.

Чтобы расширить ответ, предоставленный @Orion Edwards, вы можете сделать это полностью из кода программной части (без установленных стилей).По сути, создайте собственный класс, который наследуется от Border, у которого для дочернего элемента установлено значение TextBox.В приведенном ниже примере предполагается, что вам нужна только одна линия и что граница является дочерним элементом Canvas.Также предполагается, что вам потребуется настроить свойство MaxLength TextBox в зависимости от ширины границы.В приведенном ниже примере курсор Border также задается для имитации текстового поля, устанавливая для него тип 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;
        }
    }
}

Я думаю, что лучше использовать Label (или TextBlock) в Label, вы не можете прикрепить событие мыши непосредственно к элементу управления границей, наконец, оно прикрепляется к TextBlock, это моя рекомендация:

<Label 
    Height="32"
    VerticalContentAlignment="Center"
    HorizontalContentAlignment="Stretch"
    MouseLeftButtonUp="MenuItem_MouseLeftButtonUp">
    <TextBlock Padding="32 0 10 0">
        Label with click event
    </TextBlock>
</Label>
  <TextBox AcceptsReturn="True" 
           TextWrapping="Wrap"  
           VerticalContentAlignment="Top" >
  </TextBox>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top