0

カスタムのLabelクラスがありますが、描画されたテキストが収まりません。私はここで何が間違っているのですか?

class MyLabel: Label
{
    public MyLabel()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, Color.Black, Color.LightGray, LinearGradientMode.ForwardDiagonal))
            e.Graphics.DrawString(Text, Font, brush, ClientRectangle);
    }
}

MyLabelのテキストを「123456790123456790」(AutoSize = true)に設定すると、Designer(または実行時)に「1234567890123456789」(最後のゼロはありませんが、スペースがあります)が表示されます。「1234567890123456789012345678901234567890」を試してみると、「1234567890 1234567890 1234567890 12345678」(「90」はありませんが、スペースがあります)が表示されます。

4

3 に答える 3

2
e.Graphics.DrawString(Text, Font, brush, ClientRectangle);

間違ったテキスト レンダリング方法を使用しています。Label クラスは、TextRenderer.MeasureText() の戻り値に基づいて自動的にサイズを調整します。したがって、TextRenderer.DrawText() を使用して、まったく同じレンダリング出力を取得する必要があります。ラベルの UseCompatibleTextRendering プロパティを true に設定することもできますが、これは最初の選択ではありません。

于 2013-02-26T12:29:21.030 に答える
0

これは、「グラデーションテキストカラーの自動サイズラベル」と言い換えることができる、説明されている問題の解決策です (最善の解決策ではない可能性があります)。

class MyLabel: Label
{
    private bool _autoSize = true;
    /// <summary>
    /// Get or set auto size
    /// </summary>
    public new bool AutoSize
    {
        get { return _autoSize; }
        set
        {
            _autoSize = value;
            Invalidate();
        }
    }

    public MyLabel()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
        base.AutoSize = false;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // auto size
        if (_autoSize)
        {
            SizeF size = e.Graphics.MeasureString(Text, Font);
            if (ClientSize.Width < (int)size.Width + 1 || ClientSize.Width > (int)size.Width + 1 ||
            ClientSize.Height < (int)size.Height + 1 || ClientSize.Height > (int)size.Height + 1)
            {
                // need resizing
                ClientSize = new Size((int)size.Width + 1, (int)size.Height + 1);
                return;
            }
        }
        using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, Color.Black, Color.LightGray, LinearGradientMode.ForwardDiagonal))
        e.Graphics.DrawString(Text, Font, brush, ClientRectangle);
    }
}

背後にあるアイデアは非常に単純です。必要なテキストのサイズが ClientSize と異なる場合は、AutoSize をオーバーライドし、Paint イベント内で処理します (すべてを 1 か所で処理します)。1 つのことは、幅と高さに +1 を追加する必要があることです。これは、SizeF には分数があり、1 ピクセルを緩めるよりも +1 ピクセルを多くして、テキストが収まらない場合があるためです。

于 2013-02-26T14:13:52.477 に答える
0

Graphics.MeasureStringを使用して境界ボックスの必要なサイズを取得し、ラベルの表面のサイズをそのサイズに設定します。

于 2013-02-26T11:51:01.293 に答える