WPF TextBlock'ta metin dikey hizalaması


228

Bir TextBlock içindeki metne dikey orta hizalamayı nasıl atayabilirim? TextAlignment özelliğini buldum ancak yatay metin hizalaması içindir. Dikey metin hizalaması için nasıl yaparım?


@shr ve diğerleri: TextAlignmentyalnızca yatay hizalamayı etkiler, dikey hizalamayı etkilemez (sorunun belirttiği gibi).
Drew Noakes

Yanıtlar:


284

Bir Textblock kendisi dikey hizalama yapamaz

Bulduğum bunu yapmanın en iyi yolu, metin bloğunu bir kenarlığın içine koymaktır, böylece kenarlık sizin için hizalamayı yapar.

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

Not: Bu, işlevsel olarak bir ızgara kullanmaya eşdeğerdir, sadece kontrollerin, düzeninizin geri kalanıyla hangisinin daha uygun olduğuna nasıl uymasını istediğinize bağlıdır.


22
+1 Dikey hizalamanın etkili olması için kenarlığın yüksekliği ayarlanmalıdır.
Tim Lloyd

21
Ayrıca, TextBlock öğesinin belirtilen bir yüksekliği olamaz veya dikey olarak ortalanmaz.
pearcewg

20
@gav - TextAlignment yalnızca yatay hizalama yapıyor ... soru dikey hizalama hakkında
Orion Edwards

@TimLloyd - Bunun her zaman doğru olduğundan emin değilim. Bu kurulum var, kenarlık yüksekliği "Otomatik" ve iyi çalışıyor. Yıldızlı satır yüksekliklerine (ve satırdaki diğer şeylere) sahip bir ızgara hücresindedir.
Bob Sammers

97

Orion Edwards Answer her durum için çalışırken , kenarlığı eklemek ve bunu her yapmak istediğinizde kenarlığın özelliklerini ayarlamak acı verici olabilir. Başka bir hızlı yol, metin bloğunun dolgusunu ayarlamaktır:

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

11
Bence bu en parlak cevap.
Boppity Bop

1
Bu sadece yazı tipi 16 piksel boyutunda değilse işe yaramaz !?
C4d

1
Kabul edilen cevap, TextBox'ın gerçek kenarlıklarını doğru bir şekilde dikey olarak hizalayacaktır, ancak içindeki gerçek metin üzerinde bir etkisi yok gibi görünüyor ... ki OP'nin amacı olduğundan eminim. Bu çözüm uygun bir TextVerticalAlignment özelliği yerine çalışır ve benim oyumu alır. :)
Trekkie

Bloktaki dinamik içerik ne olacak, 2 veya 5 satır farklı dolgu gerektirmez, ayrıca 24pt yazı tiplerine karşı 10pt
Reahreic

57

TextBlock, dikey metin hizalamasını desteklemez.

Metin bloğu bir kılavuz ile sararak ve HorizontalAlignment = "Stretch" ve VerticalAlignment = "Center" ayarlayarak bu sorunu gidermek.

Bunun gibi:

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

+1 Sınır tabanlı yaklaşımda olduğu gibi Izgara Yüksekliğini ayarlamanız bile gerekmez.
Efran Cobisi

Bu yaklaşımın benim için en uygun olduğunu gördüm. Ben paylaşımlı, dinamik gösterge ışıkları oluşturma TextBlocküzerinde Ellipsebir iç Grid. Genişlik ve yükseklik özelliklerimi bağlamaya veya zor bir şey yapmaya gerek yok.
Çeltik

17

Metin bloğu yerine etiketi kullanabilirsiniz.

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

3
Güzel, Etikette VerticalContentAlignment var. Greeeat. +1
Ignacio Soler Garcia

3
OP'nin bir TextBlock kullanması gerekip gerekmediği veya bir Etiket ile kaçabileceği belli değil. Bir Etiket kullanmak ihtiyacım olan şey için çalıştı. +1
Steve Kalemkiewicz

19
Bu, dikey hizalamanın nasıl uygulanacağı değil, dikey metnin nasıl üretileceği sorusunu cevaplar!
Sebastian Negraszus

26
Bu soru meta üzerinde tartışılıyor: meta.stackoverflow.com/questions/305572/…
NathanOliver

6

Metin kaydırma olmadan yapabiliyorsanız , TextBlock yerine bir Label değiştirmenin bunu yapmanın en kısa yolu olduğunu düşünüyorum. Aksi takdirde, geçerli diğer cevaplardan birini izleyin.

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

6

TextBlockiçeriğinin dikey hizalanmasını desteklemez. Eğer kullanmanız gerekiyorsa TextBlocko zaman kendi üst göre de uyum sağlamak zorunda.

Kullanabileceğiniz Ancak eğer Labelyerine (ve onlar çok benzer özelliğe sahip do) o zaman yapabilirsiniz metin içeriğini konumlandırmak:

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

LabelEtiketin metin merkezli olacak, yani varsayılan olarak kendi sınırları doldurmak için uzatılır.


3

Benim için VerticalAlignment="Center"bu sorunu giderir.
Bunun nedeni, TextBlockbir ızgaraya sarılmış olması olabilir , ancak wpf'deki hemen hemen her şey de öyle.


1

Ben metin kutusu stilini değiştirmek (yani:) controltemplateve sonra PART_ContentHostMerkezi dikey hizalama değiştirmek hile yapacağını buldum


OP TextBlocks hakkında soru soruyor. ControlTemplate'leri yok.
ANeves

1

Sadece kıkırdamalar için, bu XAML'a bir koşuşturma verin. 'Hizalama' olmadığı için mükemmel değildir, ancak paragraf içindeki metin hizalamasını ayarlamanıza izin verir.

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

1

TextBlock'un yüksekliğini göz ardı edebiliyorsanız, bunu kullanmanız daha iyidir:

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

1

Benim durumumda, TextBlockekranı daha güzel hale getirmek için bunu yaptım .

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

Metni alttan daha ileriye götürmenin hilesi

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


0

Biraz farklı yapmam gerektiğini buldum. Benim sorunum yazı tipi boyutunu değiştirirseniz, metin satırında TextBoxes geri kalanı ile altta kalmak yerine TextBox içinde yukarı taşımak olacaktır. Dikey hizalamayı yukarıdan aşağıya doğru değiştirerek, yazı tipini programlı olarak 20'den 14'e ve arkaya değiştirebildim, metnin yerçekimini altta tuttum ve işleri düzenli tuttum. Bunu nasıl yapacağınız aşağıda açıklanmıştır:

resim açıklamasını buraya girin


0

Dikey olarak hizalanmış tek satırlık TextBox.

@Orion Edwards tarafından verilen cevabı genişletmek için, kodun arkasından tam olarak bunu yapardınız (stil ayarlanmadı). Temel olarak, alt öğesi TextBox olarak ayarlanmış olan Border öğesinden devralınan özel bir sınıf oluşturun. Aşağıdaki örnek, yalnızca tek bir satır istediğinizi ve kenarlığın bir Tuval'in alt öğesi olduğunu varsayar. Ayrıca TextBox'ın MaxLength özelliğini Kenarlığın genişliğine göre ayarlamanız gerektiğini varsayar. Aşağıdaki örnek ayrıca Kenarlık imlecini bir Metin Kutusunu 'IBeam' türüne ayarlayarak taklit edecek şekilde ayarlar. '3' kenar boşluğu, TextBox öğesinin kenarlığın soluna tam olarak hizalanmayacağı şekilde ayarlanır.

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

Sınıf:

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

Bir Etiket içine bir Etiket (veya TextBlock) kullanmak daha iyi olduğunu düşünüyorum, bir fare olayı doğrudan sınır kontrolüne ekleyemezsiniz, nihayet TextBlock'a eklenir, bu benim tavsiyem:

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

0

Merkez hizalı metin bloğuna ulaşmak için kolay ve hızlı bir yol olarak kenarlık ve arka plan içermeyen bir metin kutusu kullanmanın akıllıca olduğunu düşünüyorum

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

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

1
Soru a içindi TextBlock, değil TextBox. -1
KnorxThieus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.