Etiqueta vertical C # en Windows Forms

¿Es posible mostrar una etiqueta verticalmente en Windows Forms ?

Las tags son fáciles, todo lo que tienes que hacer es anular el evento Paint y dibujar el texto verticalmente. Tenga en cuenta que GDI está optimizado para dibujar texto horizontalmente. Si gira texto (incluso si gira a través de múltiplos de 90 grados) se verá notablemente peor.

Quizás lo mejor que puede hacer es dibujar su texto (o hacer que una etiqueta se dibuje) en un bitmap, luego mostrar el bitmap rotado.

Cierto código de C # para dibujar un control personalizado con texto vertical. Tenga en cuenta que el texto ClearType NUNCA funciona si el texto no es horizontal:

 using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; public partial class VerticalLabel : UserControl { public VerticalLabel() { InitializeComponent(); } private void VerticalLabel_SizeChanged(object sender, EventArgs e) { GenerateTexture(); } private void GenerateTexture() { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; format.Trimming = StringTrimming.EllipsisCharacter; Bitmap img = new Bitmap(this.Height, this.Width); Graphics G = Graphics.FromImage(img); G.Clear(this.BackColor); SolidBrush brush_text = new SolidBrush(this.ForeColor); G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; G.DrawString(this.Name, this.Font, brush_text, new Rectangle(0, 0, img.Width, img.Height), format); brush_text.Dispose(); img.RotateFlip(RotateFlipType.Rotate270FlipNone); this.BackgroundImage = img; } } 

Crea una clase myLabel que pueda rotar su texto en cualquier ángulo especificado por ti.

Puede usarlo por código o simplemente arrastrándolo desde ToolBox

 using System.Drawing; class myLabel:System.Windows.Forms.Label { public int RotateAngle { get; set; } // to rotate your text public string NewText { get; set; } // to draw text protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { Brush b =new SolidBrush(this.ForeColor); e.Graphics.TranslateTransform(this.Width / 2, this.Height / 2); e.Graphics.RotateTransform(this.RotateAngle); e.Graphics.DrawString(this.NewText, this.Font,b , 0f, 0f); base.OnPaint(e); } } 

Ahora este control personalizado se usa en su formulario.

Debes establecer las propiedades a continuación

  1. mylbl.Text = ""; //which can be changed by NewText property 2. mylbl.AutoSize = false; // adjust according to your text 3. mylbl.NewText = "Hello"; // whatever you want to display 4. mylbl.ForeColor = Color.Red; // color to display 5. mylbl.RotateAngle = -90; //angle to rotate 

Amplié la respuesta de Javed Akram para redimensionar el widget automáticamente (necesitaba esta característica). Funciona tanto para angularjs positivos como negativos, como dice Javed:

  1. mylbl.Text = ""; // which can be changed by NewText property 2. mylbl.AutoSize = false; // adjust according to your text 3. mylbl.NewText = "Hello"; // whatever you want to display 4. mylbl.ForeColor = Color.Red; // color to display 5. mylbl.RotateAngle = -90; // angle to rotate 

Aquí está el código:

 public class RotatingLabel : System.Windows.Forms.Label { private int m_RotateAngle = 0; private string m_NewText = string.Empty; public int RotateAngle { get { return m_RotateAngle; } set { m_RotateAngle = value; Invalidate(); } } public string NewText { get { return m_NewText; } set { m_NewText = value; Invalidate(); } } protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { Func DegToRad = (angle) => Math.PI * angle / 180.0; Brush b = new SolidBrush(this.ForeColor); SizeF size = e.Graphics.MeasureString(this.NewText, this.Font, this.Parent.Width); int normalAngle = ((RotateAngle % 360) + 360) % 360; double normaleRads = DegToRad(normalAngle); int hSinTheta = (int)Math.Ceiling((size.Height * Math.Sin(normaleRads))); int wCosTheta = (int)Math.Ceiling((size.Width * Math.Cos(normaleRads))); int wSinTheta = (int)Math.Ceiling((size.Width * Math.Sin(normaleRads))); int hCosTheta = (int)Math.Ceiling((size.Height * Math.Cos(normaleRads))); int rotatedWidth = Math.Abs(hSinTheta) + Math.Abs(wCosTheta); int rotatedHeight = Math.Abs(wSinTheta) + Math.Abs(hCosTheta); this.Width = rotatedWidth; this.Height = rotatedHeight; int numQuadrants = (normalAngle >= 0 && normalAngle < 90) ? 1 : (normalAngle >= 90 && normalAngle < 180) ? 2 : (normalAngle >= 180 && normalAngle < 270) ? 3 : (normalAngle >= 270 && normalAngle < 360) ? 4 : 0; int horizShift = 0; int vertShift = 0; if (numQuadrants == 1) { horizShift = Math.Abs(hSinTheta); } else if (numQuadrants == 2) { horizShift = rotatedWidth; vertShift = Math.Abs(hCosTheta); } else if (numQuadrants == 3) { horizShift = Math.Abs(wCosTheta); vertShift = rotatedHeight; } else if (numQuadrants == 4) { vertShift = Math.Abs(wSinTheta); } e.Graphics.TranslateTransform(horizShift, vertShift); e.Graphics.RotateTransform(this.RotateAngle); e.Graphics.DrawString(this.NewText, this.Font, b, 0f, 0f); base.OnPaint(e); } } 

¡Encontré una forma de hacerlo simplemente sin agregar código o clases a tu proyecto!

Cuando crees tu etiqueta, simplemente agrega:

 this.label1.text = "V\nE\nR\nT\nI\nC\nA\nL\n"; 

¡Esto funcionó para mí!

Puede rotar texto en lugar del control de etiqueta en el evento OnPaint o en el método Paint :

 private void uc1_Paint(object sender, PaintEventArgs e) { string Name; var g = e.Graphics; g.DrawString(Name, new Font("Tahoma", 8), Brushes.Black, 0, 0, new StringFormat(StringFormatFlags.DirectionVertical)); } 

Piezas usadas de otros

Jeremy

 public partial class VerticalLabel_UserControl : UserControl { private IComponentChangeService _changeService; private string strPropertyText = "Vertical Text"; public VerticalLabel_UserControl() { InitializeComponent(); } [EditorBrowsable(EditorBrowsableState.Always)] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [Bindable(true)] public override string Text { get { return base.Text; } set { base.Text = value; this.Invalidate(); } } private void VerticalLabel_UserControl_SizeChanged(object sender, EventArgs e) { GenerateTexture(); } protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); } private void GenerateTexture() { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; // format.Trimming = StringTrimming.EllipsisCharacter; Bitmap img = new Bitmap(this.Height, this.Width); Graphics G = Graphics.FromImage(img); G.Clear(this.BackColor); SolidBrush brush_text = new SolidBrush(this.ForeColor); G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; G.DrawString(this.strPropertyText, this.Font, brush_text, new Rectangle(0, 0, img.Width, img.Height), format); img.RotateFlip(RotateFlipType.Rotate270FlipNone); this.BackgroundImage = img; brush_text.Dispose(); } public override System.ComponentModel.ISite Site { get { return base.Site; } set { _changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService)); if (_changeService != null) _changeService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged); base.Site = value; if (!DesignMode) return; _changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService)); if (_changeService != null) _changeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged); } } private void OnComponentChanged(object sender, ComponentChangedEventArgs ce) { VerticalLabel_UserControl label = ce.Component as VerticalLabel_UserControl; if (label == null || !label.DesignMode) return; if (((IComponent)ce.Component).Site == null || ce.Member == null || ce.Member.Name != "Text") return; //Causes the default text to be updated string strName = this.Name.ToLower(); string strText = this.Text.ToLower(); if (strText.Contains(strName)) { this.Text = "Vertical Text"; } else { strPropertyText = this.Text; } //Prints the text vertically GenerateTexture(); } } 

Actualización de 2015 en una publicación anterior. Dado que la mayoría de las otras respuestas parecen afectar mucho al diseñador de VS2013 en términos de usabilidad, sugeriría esta solución:

http://www.codeproject.com/Articles/19774/Extended-Vertical-Label-Control-in-C-NET

Funciona absolutamente Lo encontré en la red y poco cambió

 using System; using System.Drawing; using System.Windows.Forms; using System.Drawing.Drawing2D; using System.ComponentModel; public class VerticalLabel : System.Windows.Forms.Label { private bool bFlip = true; public VerticalLabel() { } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.Trimming = StringTrimming.None; stringFormat.FormatFlags = StringFormatFlags.DirectionVertical; Brush textBrush = new SolidBrush(this.ForeColor); Matrix storedState = g.Transform; if (bFlip) { g.RotateTransform(180f); g.TranslateTransform(-ClientRectangle.Width,-ClientRectangle.Height); } g.DrawString( this.Text, this.Font, textBrush, ClientRectangle, stringFormat); g.Transform = storedState; } [Description("When this parameter is true the VLabel flips at 180 degrees."),Category("Appearance")] public bool Flip180 { get { return bFlip; } set { bFlip = value; this.Invalidate(); } } } 

Acabo de desactivar la propiedad AutoSize y redimensioné la etiqueta verticalmente. Hice la etiqueta lo suficientemente amplia para un solo personaje. Luego cambié TextAlign al centro para que la alineación se viera mejor. Esto funciono muy bien para mi.