web-dev-qa-db-ja.com

WindowsフォームのC#垂直ラベル

Windows Forms でラベルを垂直に表示することは可能ですか?

26
Toto

ラベルは簡単です。必要なことは、Paintイベントをオーバーライドし、テキストを垂直に描画することだけです。 GDIは、テキストを水平に描画するために最適化されています。テキストを回転させると(90度の倍数を回転させても)著しく悪化します。

おそらく、最善の方法は、テキストをビットマップに描画し(またはラベルを描画して)、ビットマップを回転させて表示することです。

縦書きテキストでカスタムコントロールを描画するための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;
    }
}
20
David Rutten

指定した任意の角度でTextを回転できるクラスmyLabelを作成します。

コードまたは単にツールボックスからドラッグして使用できます

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
16
Javed Akram

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

コードは次のとおりです。

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

プロジェクトにコードやクラスを追加せずに単純に行う方法を見つけました!

ラベルを作成するときに、次を追加するだけです。

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

これは私のために働いた!

5
Yor

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

古い投稿の2015年の更新。他のほとんどの回答は、使いやすさの点でVS2013のデザイナーに大きな影響を与えるように見えるため、このソリューションをお勧めします。

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

1
Hexo

それは絶対に機能します。ネットで見つけたが、ほとんど変わっていない

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

他からの中古品

ジェレミー

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

AutoSizeプロパティをオフにして、ラベルのサイズを垂直に変更しました。ラベルを1文字だけに十分な幅にしました。次に、TextAlignを中央に変更して、配置をより見やすくしました。これは私にとってはうまくいきました。

0
JasonD