Подтвердить что ты не робот

Вертикальная метка С# в Windows Forms

Можно ли отображать этикетку по вертикали в Windows Forms?

4b9b3361

Ответ 1

Ярлыки просты, все, что вам нужно сделать, это переопределить событие Paint и нарисовать текст по вертикали. Обратите внимание, что GDI оптимизирован для рисования текста по горизонтали. Если вы поворачиваете текст (даже если вы вращаетесь через кратные 90 градусов), это будет заметно хуже.

Возможно, самое лучшее, что можно сделать, это нарисовать текст (или получить ярлык для рисования) на растровое изображение, а затем отобразить растровое изображение.

Некоторый код С# для рисования пользовательского элемента управления с вертикальным текстом. Обратите внимание, что текст ClearType NEVER работает, если текст не является горизонтальным:

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

Ответ 2

Создайте класс myLabel, который может вращать его. Текст по любому указанному вами углу.

Вы можете использовать его по коду или просто перетаскивать из 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);
    }
}

Теперь этот настраиваемый элемент управления используется в вашей форме.

Вы должны установить ниже свойства

 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

Ответ 3

Я расширил Javed Akram, чтобы автоматически изменить размер виджета (мне нужна эта функция). Он работает как с положительным, так и с отрицательным углом, так, как утверждает Джавед:

 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

Вот код:

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

Ответ 4

Я нашел способ просто сделать это без добавления кода или классов в ваш проект!

Когда вы создаете свой ярлык, просто добавьте:

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

Это сработало для меня!

Ответ 5

Вы можете поворачивать текст вместо элемента управления меткой в ​​методе 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));
}

Ответ 6

Используемые куски из других

Джереми

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

Ответ 7

2015 обновление по старой почте. Поскольку большинство других ответов, похоже, сильно влияют на конструктор VS2013 с точки зрения удобства использования, я бы предложил это решение:

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

Ответ 8

Это абсолютно работает. Я нашел его в сети и немного изменил

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

Ответ 9

Я просто отключил свойство AutoSize и изменил размер метки по вертикали. Я сделал ярлык достаточно для одного персонажа. Затем я изменил TextAlign на центр, чтобы выравнивание выглядело лучше. Это отлично поработало для меня.