Alineación vertical del texto en WPF TextBlock
-
18-09-2019 - |
Pregunta
¿Cómo se asigna la alineación centrada vertical al texto dentro de un TextBlock? He encontrado la propiedad TextAlignment pero es para la alineación horizontal del texto. ¿Cómo lo hago para la alineación de texto vertical?
Solución
A Textblock en sí no puede hacer la alineación vertical
La mejor manera de hacer esto que he encontrado es poner el bloque de texto dentro de un borde, por lo que la frontera hace la alineación para usted.
<Border BorderBrush="{x:Null}" Height="50">
<TextBlock TextWrapping="Wrap" Text="Some Text" VerticalAlignment="Center"/>
</Border>
Nota: Este es funcionalmente equivalente a utilizar una cuadrícula, sólo depende de cómo desea que los controles de encajar con el resto de su diseño en cuanto a cuál es más adecuado
Otros consejos
Orion Edwards respuesta funciona para cualquier situación, puede ser un dolor para agregar la frontera y establecer las propiedades de la frontera cada vez que desee hacerlo. Otra forma rápida es fijar el relleno del bloque de texto:
<TextBlock Height="22" Padding="3" />
El TextBlock no admite la alineación de texto vertical.
Yo trabajo en torno a esta envolviendo el bloque de texto con una cuadrícula y el establecimiento de HorizontalAlignment = "Stretch" y VerticalAlignment = "centro".
De esta manera:
<Grid>
<TextBlock
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Text="Your text" />
</Grid>
Puede utilizar la etiqueta en lugar de bloque de texto.
<Label Content="Hello, World!">
<Label.LayoutTransform>
<RotateTransform Angle="270"/>
</Label.LayoutTransform>
</Label>
TextBlock
no admite la alineación vertical de su contenido. Si tiene que usar TextBlock
entonces usted tiene que alinear con respecto a su padre.
Sin embargo si se puede usar en lugar Label
(y tienen una funcionalidad muy similar), entonces puede Posición del contenido de texto:
<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
I am centred text!
</Label>
El Label
se estirará para llenar sus límites de forma predeterminada, es decir, el texto de la etiqueta se centra.
Para mí, correcciones VerticalAlignment="Center"
este problema.
Esto podría deberse a que los TextBlock
is envueltos en una cuadrícula, pero también lo es prácticamente todo en WPF.
He encontrado que la modificación del estilo de texto (es decir: controltemplate
) y luego modificar la alineación vertical PART_ContentHost
al Centro hará el truco
Sólo por diversión, dan a este XAML un torbellino. No es perfecto, ya que no es una 'alineación' pero le permite ajustar la alineación del texto dentro de un párrafo.
<TextBlock>
<TextBlock BaselineOffset="30">One</TextBlock>
<TextBlock BaselineOffset="20">Two</TextBlock>
<Run>Three</Run>
<Run BaselineAlignment="Subscript">Four</Run>
</TextBlock>
Si se puede pasar por alto la altura de TextBlock, es mejor para que usted utilice la siguiente:
<TextBlock Height="{Binding}" Text="Your text"
TextWrapping="Wrap" VerticalAlignment="Center" Width="28"/>
En mi caso, hice esto para hacer más agradable la pantalla 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>
El truco para hacer el texto más lejos de la parte inferior es establecer
Margin="0,0,0,-5"
Usted puede ver mi blog. Es posible ajustar la altura costumbre de Textblock de código subyacente. Para el ajuste de altura personalizada es necesario establecer dentro de una frontera o StackPanel
http://ciintelligence.blogspot.com/ 2011/02 / wpf-textblock-vertical de alineación-with.html
Me encontré con que tenía que hacerlo un poco diferente. Mi problema era que si cambiaba el tamaño de fuente, el texto se movería en el cuadro de texto en lugar de permanecer en la parte inferior con el resto de los cuadros de texto en la línea. Al cambiar la alineación vert de arriba a abajo que era capaz de cambiar la fuente mediante programación a partir del tamaño 20 a talla 14 y hacia atrás, manteniendo la gravedad de texto en la parte inferior y mantener las cosas ordenadas. He aquí cómo:
Para ampliar la respuesta proporcionada por @Orion Edwards, esta es la forma en que lo haría completamente de código subyacente (no hay estilos de juego). Básicamente crear una clase personalizada que hereda de Frontera que tiene su hijo a fijar a un cuadro de texto. El ejemplo siguiente se supone que sólo desea una sola línea y que la frontera es un niño de un lienzo. También se supone que tendría que ajustar la propiedad MaxLength del cuadro de texto en función del ancho de la frontera. El ejemplo siguiente también establece el cursor de la frontera para imitar un cuadro de texto estableciéndolo en el tipo 'IBeam'. Un margen de '3' se establece para que el cuadro de texto no está totalmente alineado a la izquierda de la frontera.
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);
Clase:
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;
}
}
}
Creo que es mejor usar una etiqueta (o TextBlock) en una etiqueta, no se puede adjuntar un evento de ratón directamente en el control de fronteras, por último, se adjunta en el TextBlock, esta es mi recomendación:
<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>