Windows 窗体中的 C# 垂直标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1371943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:47:32  来源:igfitidea点击:

C# vertical label in a Windows Forms

c#winformslabel

提问by Toto

Is it possible to display a label vertically in a Windows Forms?

是否可以在Windows 窗体中垂直显示标签?

回答by David Rutten

Labels are easy, all you have to do is override the Paintevent and draw the text vertically. Do note that GDI is optimised for Drawing text horizontally. If you rotate text (even if you rotate through multiples of 90 degrees) it will looks notably worse.

标签很容易,您所要做的就是覆盖Paint事件并垂直绘制文本。请注意,GDI 针对水平绘制文本进行了优化。如果您旋转文本(即使您旋转了 90 度的倍数),它看起来会明显更糟。

Perhaps the best thing to do is draw your text (or get a label to draw itself) onto a bitmap, then display the bitmap rotated.

也许最好的办法是在位图上绘制您的文本(或获取一个标签来绘制自己),然后显示旋转的位图。

Some C# code for drawing a Custom Control with vertical text. Note that ClearType text NEVER works if the text is not horizontal:

一些用于绘制带有垂直文本的自定义控件的 C# 代码。请注意,如果文本不是水平的,则 ClearType 文本永远不会起作用:

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

回答by Javed Akram

Create a class myLabelwhich can rotate it's Text on any angle specified by you.

创建一个myLabel可以在您指定的任何角度旋转它的文本的类。

You can use it by code or simply dragging from ToolBox

您可以通过代码或简单地从 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);
    }
}

Now this custom control is used into your form.

现在这个自定义控件用于您的表单。

You have to set below properties

您必须设置以下属性

 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

回答by Buddy

I expanded on Javed Akram's answer to resize the widget automatically (I needed this feature). It works for both positive and negative angles, the way that Javed states:

我扩展了 Javed Akram 的答案以自动调整小部件的大小(我需要这个功能)。它适用于正角和负角,就像 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

Here is the code:

这是代码:

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<double, double> 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);
    }
}

回答by Yor

I found a way to simply do it without adding code or classes to your project!

我找到了一种简单的方法,无需向您的项目添加代码或类!

When you create your label, simply add:

创建标签时,只需添加:

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

This worked for me!

这对我有用!

回答by Harry Sarshogh

You can rotate text instead of the label control in the OnPaintevent or Paintmethod:

您可以在OnPaint事件或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));
}

回答by Jeremy

Used pieces from others

别人的二手货

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

回答by Hexo

2015 update on an old post. Since most of the other answers seem to heavily affect VS2013's designer in terms of usability, I'd suggest this solution:

2015 更新旧帖子。由于大多数其他答案似乎在可用性方面严重影响了 VS2013 的设计师,因此我建议使用以下解决方案:

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

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

回答by Nasuh Levent YILDIZ

It absolutely works. I found it on net and little changed

它绝对有效。我在网上找到的,变化不大

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

回答by JasonD

I just turned off the AutoSize property and resized the label vertically. I made the label wide enough for only one character. Then I changed TextAlign to center to make the alignment look better. This worked great for me.

我刚刚关闭了 AutoSize 属性并垂直调整了标签的大小。我使标签足够宽,只能容纳一个字符。然后我将 TextAlign 更改为 center 以使对齐看起来更好。这对我很有用。