2009-09-29 18 views
179

Jak przypisać pionowe wyrównanie do środka tekstu w bloku tekstowym? Znalazłem właściwość TextAlignment, ale służy do poziomego wyrównania tekstu. Jak mogę to zrobić dla pionowego wyrównania tekstu?Wyrównanie tekstu w pionie w WPF TextBlock

+0

@shr i inne: zwróć uwagę, że "TextAlignment" wpływa tylko na wyrównanie w poziomie, a nie na * wyrównanie pionowe * (w zależności od pytania). –

Odpowiedz

223

TextBlock nie może zrobić Vertical Alignment

Najlepszym sposobem, aby to zrobić, że znalazłem to umieścić textblock wewnątrz granicy, więc granicę robi wyrównanie dla ciebie.

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

Uwaga: To jest funkcjonalnie równoważne użyciu siatki, to po prostu zależy od tego jak chcesz kontrole, aby dopasować się do reszty układu, co do których jedna jest bardziej odpowiedni

+18

+1 Wysokość obramowania musi być ustawiona, aby wyrównać w pionie. –

+13

Ponadto, TextBlock nie może mieć określonej wysokości lub nie będzie wyśrodkować w pionie. – pearcewg

+17

@gav - TextAlignment wykonuje tylko wyrównanie w poziomie ... pytanie dotyczy pionowego wyrównania –

46

Funkcja TextBlock nie obsługuje wyrównania tekstu w pionie.

Pracuję nad tym poprzez zawijanie bloku tekstu za pomocą siatki i ustawianie HorizontalAlignment = "Stretch" i VerticalAlignment = "Center".

Jak to: Sam

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

+1 Nie trzeba nawet ustawiać wysokości siatki, tak jak w przypadku podejścia na granicy. –

+0

Uważam, że to podejście działa najlepiej dla mnie. Tworzę dynamiczne diody sygnalizacyjne nakładając 'TextBlock' na' Ellipse' wewnątrz 'Grid'. Nie musisz wiązać moich właściwości szerokości i wysokości ani robić niczego trudnego. – paddy

1

Dla mnie VerticalAlignment="Center" rozwiązuje ten problem.
Może to być spowodowane tym, że TextBlock jest zawinięty w siatkę, ale tak też jest praktycznie wszystko w WPF.

76

Podczas gdy Orion Edwards Answer działa w każdej sytuacji, może to być ból, aby dodać granicę i ustawić właściwości granicy za każdym razem, gdy chcesz to zrobić. Innym szybkim sposobem jest ustawienie dopełnienia bloku tekstowego:

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

Myślę, że to jest najbardziej błyskotliwa odpowiedź. –

+1

To, czego szukałem !!! Dziękuję Ci! –

+1

Działa to tylko wtedy, gdy czcionka ma rozmiar 16 pikseli, prawda? – C4u

14

Można użyć etykiety zamiast textblock.

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

Przyjemnie, etykieta ma VerticalContentAlignment. Greeeat. +1 –

+3

Nie jest jasne, czy PO potrzebował użyć blokady TextBlock, czy też mógł uciec z etykietą. Używanie etykiety działało zgodnie z potrzebami. +1 –

+18

To odpowiada na pytanie, jak wytworzyć tekst pionowy, a nie w jaki sposób zastosować pionowe wyrównanie! –

1

Znalazłem, że modyfikacja stylu pola tekstowego (np: controltemplate), a następnie modyfikując PART_ContentHost pionowe wyrównanie do centrum rade

+0

OP pyta o TextBlocks. Nie mają ControlTemplates. – ANeves

1

Tylko dla chichotów, dać ten XAML wir. Nie jest idealny, ponieważ nie jest "wyrównaniem", ale pozwala dostosować wyrównanie tekstu w akapicie.

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

Jeśli można przeoczyć wysokość TextBlock, to lepiej, aby to wykorzystać:

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

W moim przypadku zrobiłem to, aby wyświetlacz TextBlock ładniejszy.

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

Sztuką aby tekst dalej od dołu jest ustawienie

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

znalazłem musiałem zrobić to nieco inaczej.Mój problem polegał na tym, że gdybym zmienił rozmiar czcionki, tekst przesunąłby się w TextBox zamiast pozostawać na dole z resztą TextBox'ów na linii. Zmieniając wyrównanie vertu z góry na dół, byłem w stanie zmienić czcionkę programowo z rozmiaru 20 na rozmiar 14 & z powrotem, zachowując grawitację tekstu na dole i utrzymując wszystko w porządku. Oto jak:

enter image description here

1

Vertically aligned single line TextBox.

Aby rozwinąć na odpowiedź udzieloną przez @Orion Edwards, to jak byś w pełni zrobić z kodu źródłowego (bez style set). Zasadniczo utwórz klasę niestandardową, która dziedziczy po Border, która ma zestaw Child, do TextBox. Poniższy przykład zakłada, że ​​potrzebujesz tylko jednej linii i że granica jest dzieckiem płótna. Zakłada również, że musisz dostosować właściwość MaxLength w TextBox na podstawie szerokości obramowania. Poniższy przykład ustawia również kursor granicy, aby naśladować pole tekstowe, ustawiając go na typ "IBeam". Margines "3" jest ustawiony tak, aby pole tekstowe nie było absolutnie wyrównane do lewej krawędzi.

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

Klasa:

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

myślę, lepiej jest użyć etykiety (lub TextBlock) na etykiecie, nie można dołączyć zdarzenie myszy bezpośrednio w kontroli granicznej, w końcu jest on dołączony w TextBlock, to moja poleca:

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

Jeśli można zrobić bez text wrapping, myślę, że zastąpienie TextBlock z etykietą jest najbardziej zwięzły sposób, aby to zrobić. W przeciwnym razie wykonaj jedną z innych poprawnych odpowiedzi.

<Label Content="Some Text" VerticalAlignment="Center"/> 
0
<TextBox AcceptsReturn="True" 
      TextWrapping="Wrap" 
      VerticalContentAlignment="Top" > 
    </TextBox> 
+0

Pytanie dotyczyło 'TextBlock', a nie' TextBox'. -1 – KnorxThieus

0

TextBlock nie obsługuje pionowe wyrównanie jego treści. Jeśli musisz użyć TextBlock, musisz dopasować go do swojego rodzica.

Jednak jeśli można użyć Label zamiast (i mają bardzo podobną funkcjonalność), to może pozycja zawartość tekstu:

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

Label potrwają do wypełnienia swoich granic domyślnie, co oznacza, że tekst etykiety zostanie wyśrodkowany.

Powiązane problemy