Căn chỉnh văn bản trong WPF TextBlock


228

Làm cách nào để gán căn chỉnh trung tâm dọc cho văn bản bên trong TextBlock? Tôi tìm thấy thuộc tính TextAlocation nhưng nó là để căn chỉnh văn bản ngang. Làm thế nào để tôi làm điều đó cho căn chỉnh văn bản dọc?


@shr và những người khác: lưu ý rằng TextAlignmentchỉ ảnh hưởng đến căn chỉnh ngang, không liên kết dọc (như câu hỏi đề cập).
Drew Noakes

Câu trả lời:


284

Bản thân Textblock không thể thực hiện căn chỉnh dọc

Cách tốt nhất để làm điều này mà tôi đã tìm thấy là đặt textblock bên trong một đường viền, do đó đường viền sẽ căn chỉnh cho bạn.

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

Lưu ý: Điều này có chức năng tương đương với việc sử dụng lưới, nó chỉ phụ thuộc vào cách bạn muốn các điều khiển phù hợp với phần còn lại của bố cục của bạn như cách nào phù hợp hơn


22
+1 Chiều cao của đường viền phải được đặt để căn chỉnh dọc có hiệu lực.
Tim Lloyd

21
Ngoài ra, TextBlock không thể có chiều cao được chỉ định hoặc nó sẽ không nằm ở giữa theo chiều dọc.
pearcewg

20
@gav - TextAlocation chỉ thực hiện căn chỉnh ngang ... câu hỏi là về căn chỉnh dọc
Orion Edwards

@TimLloyd - Tôi không chắc điều đó luôn đúng. Tôi đã thiết lập này, đường viền có chiều cao "Tự động" và nó hoạt động tốt. Nó nằm trong một ô lưới có chiều cao hàng được gắn dấu sao (và những thứ khác trong hàng).
Bob Sammer

97

Trong khi Orion Edwards Trả lời hoạt động cho mọi tình huống, có thể sẽ rất khó khăn khi thêm đường viền và đặt thuộc tính của đường viền mỗi khi bạn muốn làm điều này. Một cách nhanh chóng khác là đặt phần đệm của khối văn bản:

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

11
Tôi nghĩ rằng đây là câu trả lời tuyệt vời nhất.
Boppity Bop

1
Điều này chỉ hoạt động nếu phông chữ có kích thước 16px phải không!?
C4d

1
Câu trả lời được chấp nhận sẽ căn chỉnh chính xác theo chiều dọc các đường viền thực tế của TextBox, nhưng dường như nó không có ảnh hưởng đến văn bản thực tế trong ... điều mà tôi khá chắc chắn là ý định của OP. Giải pháp này hoạt động thay cho thuộc tính TextV verticalAlocation thích hợp và nhận được upvote của tôi. :)
Trekkie

Còn nội dung động trong khối thì 2 hoặc 5 dòng sẽ yêu cầu phần đệm khác nhau, phông chữ 10pt so với 24pt
Reahreic

57

TextBlock không hỗ trợ căn chỉnh văn bản dọc.

Tôi xử lý vấn đề này bằng cách gói khối văn bản bằng Lưới và đặt Ngang ngang = "Kéo dài" và Dọc dọc = "Trung tâm".

Như thế này:

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

+1 Thậm chí không cần đặt Chiều cao cho Lưới, như với cách tiếp cận dựa trên Đường viền.
Efran Cobisi

Tôi thấy phương pháp này hoạt động tốt nhất cho tôi. Tôi tạo ra đèn báo động bằng cách phủ TextBlocktrên Ellipsebên trong một Grid. Không cần phải ràng buộc các thuộc tính chiều rộng và chiều cao của tôi hoặc làm bất cứ điều gì khó khăn.
thóc

17

Bạn có thể sử dụng nhãn thay vì textblock.

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

3
Thật tuyệt, Nhãn có dọcContentAlocation. Hy sinh. +1
Ignacio Soler Garcia

3
Không rõ liệu OP có cần sử dụng TextBlock hay không hoặc có thể thoát khỏi Nhãn. Sử dụng một nhãn làm việc cho những gì tôi cần. +1
Steve Kalemkiewicz

19
Điều này trả lời câu hỏi làm thế nào để tạo văn bản dọc, không phải làm thế nào để áp dụng căn chỉnh dọc!
Sebastian Negraszus

26
Câu hỏi này đang được thảo luận trên meta: meta.stackoverflow.com/questions/305572/
Kẻ

6

Nếu bạn có thể làm mà không cần gói văn bản , tôi nghĩ rằng thay thế TextBlock bằng Nhãn là cách ngắn gọn nhất để thực hiện việc này. Nếu không, hãy làm theo một trong những câu trả lời hợp lệ khác.

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

6

TextBlockkhông hỗ trợ liên kết dọc của nội dung của nó. Nếu bạn phải sử dụngTextBlock thì bạn phải căn chỉnh nó với cha mẹ của nó.

Tuy nhiên nếu bạn có thể sử dụng Labelthay thế (và chúng có chức năng rất giống nhau) thì bạn có thể định vị nội dung văn bản:

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

Ý Labelchí sẽ kéo dài để lấp đầy giới hạn của nó theo mặc định, có nghĩa là văn bản của nhãn sẽ được căn giữa.


3

Đối với tôi, VerticalAlignment="Center"khắc phục vấn đề này.
Điều này có thể là do TextBlockđược bọc trong một lưới, nhưng sau đó thực tế là tất cả mọi thứ trong wpf.


1

Tôi đã thấy rằng sửa đổi kiểu hộp văn bản (ví dụ controltemplate:) và sau đó sửa đổi PART_ContentHostcăn chỉnh dọc thành Trung tâm sẽ thực hiện thủ thuật


OP đang hỏi về TextBlocks. Họ không có ControlTemsheet.
ANeves

1

Chỉ để cười khúc khích, hãy tạo cho XAML một vòng xoáy. Nó không hoàn hảo vì nó không phải là một 'căn chỉnh' nhưng nó cho phép bạn điều chỉnh căn chỉnh văn bản trong một đoạn văn.

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

1

Nếu bạn có thể bỏ qua chiều cao của TextBlock, tốt hơn hết là bạn nên sử dụng điều này:

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

1

Trong trường hợp của tôi, tôi đã làm điều này để làm cho TextBlockmàn hình đẹp hơn.

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

Mẹo để làm cho văn bản xa hơn từ dưới cùng là đặt

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


0

Tôi thấy tôi phải làm điều đó một chút khác nhau. Vấn đề của tôi là nếu tôi thay đổi kích thước phông chữ, văn bản sẽ di chuyển lên trong TextBox thay vì ở dưới cùng với phần còn lại của TextBoxes trên dòng. Bằng cách thay đổi căn chỉnh dọc từ trên xuống dưới, tôi có thể thay đổi phông chữ theo chương trình từ cỡ 20 sang cỡ 14 & trở lại, giữ trọng lực của văn bản ở phía dưới và giữ mọi thứ gọn gàng. Đây là cách thực hiện:

nhập mô tả hình ảnh ở đây


0

TextBox một dòng được căn chỉnh theo chiều dọc.

Để mở rộng câu trả lời được cung cấp bởi @Orion Edwards, đây là cách bạn sẽ thực hiện đầy đủ từ mã phía sau (không đặt kiểu). Về cơ bản tạo một lớp tùy chỉnh kế thừa từ Border có Con được đặt thành TextBox. Ví dụ dưới đây giả định rằng bạn chỉ muốn một dòng duy nhất và đường viền là con của Canvas. Cũng giả sử rằng bạn sẽ cần điều chỉnh thuộc tính MaxLạng của TextBox dựa trên chiều rộng của Đường viền. Ví dụ dưới đây cũng đặt con trỏ của Border để bắt chước Hộp văn bản bằng cách đặt nó thành loại 'IBeam'. Lề '3' được đặt sao cho TextBox không được căn chỉnh hoàn toàn ở bên trái đường viền.

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

Lớp học:

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

Tôi nghĩ tốt hơn là sử dụng Nhãn (hoặc TextBlock) vào Nhãn, bạn không thể đính kèm sự kiện chuột trực tiếp trong điều khiển viền, cuối cùng nó được đính kèm trong TextBlock, đây là gợi ý của tôi:

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

0

Tôi nghĩ thật khôn ngoan khi sử dụng hộp văn bản không có viền và nền như một cách dễ dàng và nhanh chóng để tiếp cận văn bản được căn giữa

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

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

1
Câu hỏi là cho một TextBlock, không TextBox. -1
KnorxThieus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.