alinhamento vertical texto no WPF TextBlock
-
18-09-2019 - |
Pergunta
Como atribuir alinhamento centro vertical ao texto dentro de um TextBlock? Eu encontrei TextAlignment propriedade, mas é para alinhamento de texto horizontal. Como posso fazê-lo para o alinhamento de texto vertical?
Solução
A própria TextBlock não pode fazer alinhamento vertical
A melhor maneira de fazer isso que eu encontrei é colocar o textblock dentro de uma borda, então a fronteira faz o alinhamento para você.
<Border BorderBrush="{x:Null}" Height="50">
<TextBlock TextWrapping="Wrap" Text="Some Text" VerticalAlignment="Center"/>
</Border>
Nota: Este é funcionalmente equivalente a usar uma grade, ele só depende de como você quer que os controles se encaixar com o resto do seu layout como a que um é mais adequado
Outras dicas
Enquanto Orion Edwards Resposta funciona para qualquer situação, pode ser uma dor de adicionar a borda e definir as propriedades de a fronteira cada vez que você quer fazer isso. Outra maneira rápida é definir o preenchimento do bloco de texto:
<TextBlock Height="22" Padding="3" />
O TextBlock não suporta alinhamento de texto vertical.
Eu contornar este envolvendo o bloco de texto com uma grade e definindo HorizontalAlignment = "Stretch" e VerticalAlignment = "center".
Como esta:
<Grid>
<TextBlock
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Text="Your text" />
</Grid>
Você pode usar etiqueta em vez de textblock.
<Label Content="Hello, World!">
<Label.LayoutTransform>
<RotateTransform Angle="270"/>
</Label.LayoutTransform>
</Label>
TextBlock
não suporta alinhamento vertical do seu conteúdo. Se você deve usar TextBlock
então você tem para alinhá-lo com respeito a seu pai.
No entanto, se você pode usar Label
vez (e eles têm uma funcionalidade muito similar), então você pode posição do conteúdo do texto:
<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
I am centred text!
</Label>
O Label
vai esticar para preencher seus limites, por padrão, o que significa que o texto do rótulo será centrada.
Para mim, correções VerticalAlignment="Center"
este problema.
Isto poderia ser porque os TextBlock
is envolto em uma grade, mas então é praticamente tudo no WPF.
Descobri que modificar o estilo de caixa de texto (ou seja: controltemplate
) e, em seguida, modificar o alinhamento vertical PART_ContentHost
ao Centro irá fazer o truque
Apenas para risos, dar a este XAML um turbilhão. Não é perfeito, pois não é um 'alinhamento', mas ele permite que você ajustar o alinhamento do texto em um parágrafo.
<TextBlock>
<TextBlock BaselineOffset="30">One</TextBlock>
<TextBlock BaselineOffset="20">Two</TextBlock>
<Run>Three</Run>
<Run BaselineAlignment="Subscript">Four</Run>
</TextBlock>
Se você pode ignorar a altura de TextBlock, é melhor para você usar este:
<TextBlock Height="{Binding}" Text="Your text"
TextWrapping="Wrap" VerticalAlignment="Center" Width="28"/>
No meu caso, eu fiz isso para tornar o mais agradável exibição 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>
O truque para tornar o texto mais longe da parte inferior é definir
Margin="0,0,0,-5"
Você pode ver meu blog post. Você pode definir a altura costume de textblock de codebehind. Para definir altura personalizada você precisará configurá-lo dentro de uma fronteira ou StackPanel
http://ciintelligence.blogspot.com/ 2011/02 / WPF-textblock-vertical-alinhamento-with.html
eu descobri que eu tinha que fazer isso um pouco diferente. Meu problema era que se eu mudasse o tamanho da fonte, o texto iria mover-se na caixa de texto em vez de estadia na parte inferior com o resto do TextBoxes na linha. Ao alterar o vert alinhamento de cima para baixo I foi capaz de mudar a fonte de programação a partir do tamanho 20 ao tamanho 14 e para trás, mantendo a gravidade de texto na parte inferior e manter as coisas arrumado. Veja como:
Para expandir a resposta fornecida pelo @Orion Edwards, isto é como você faria totalmente a partir do código-behind (sem estilos set). Basicamente criar uma classe personalizada que herda de Fronteira, que tem o seu Criança definido para uma caixa de texto. O exemplo abaixo assume que só deseja uma única linha e que a fronteira é um filho de um Canvas. Também assume que você precisa para ajustar a propriedade MaxLength do TextBox com base na largura da Fronteira. O exemplo que se segue também define o cursor da Fronteira para imitar uma caixa de texto, fixando-o ao tipo 'iBeam'. A margem de '3' é definido de modo que o TextBox não é absolutamente alinhados à esquerda da fronteira.
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);
Class:
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;
}
}
}
Eu acho que é melhor usar uma etiqueta (ou TextBlock) em uma etiqueta, você não pode anexar um evento do mouse diretamente no controlo das fronteiras, finalmente ele está ligado no TextBlock, esta é a minha recomendação:
<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>