【问题标题】:Label UserPaint drawn text doesn't fit标签 UserPaint 绘制的文本不适合
【发布时间】:2013-02-11 20:34:10
【问题描述】:

我有一个自定义标签类,绘制的文本不适合。 我在这里做错了什么?

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 的文本设置为“123456790 123456790”(AutoSize = true),那么我在 Designer(或在运行时)中看到“1234567890 123456789”(没有最后一个零,但是一些空间)。如果我尝试“1234567890 1234567890 1234567890 1234567890”,那么将有“1234567890 1234567890 1234567890 12345678”(没有“90”,但还有一些空间)。

【问题讨论】:

  • 如何设置标签的大小?是MyLable里面的全部代码吗?如果是,则将AutoSize 属性设置为true
  • AutoSize = true,是的。忘了说。

标签: c# winforms labels ownerdrawn


【解决方案1】:

使用Graphics.MeasureString 获得所需的边界框大小,然后将标签表面的大小设置为该大小。

【讨论】:

  • 问题不是如何设置标签大小,而是如何将文本放入给定的大小(通过 AutoSize = true)。或者也许是我还不知道的其他东西。
  • 如果您自己绘制文本,那么它可能不适合 AutoSize 提供的边界 - AutoSize 功能首先使用字符串测量来创建其边界。
【解决方案2】:
e.Graphics.DrawString(Text, Font, brush, ClientRectangle);

您使用了错误的文本呈现方法。 Label 类根据 TextRenderer.MeasureText() 的返回值自动调整自身大小。因此,您必须使用 TextRenderer.DrawText() 来获得完全相同的渲染输出。您还可以将标签的 UseCompatibleTextRendering 属性设置为 true,但这不应该是您的首选。

【讨论】:

  • 使用标签 UseCompartibleTextRendering 属性有所帮助(在Application.SetCompatibleTextRenderingDefault(true); 之前尝试过,但没有运气^^)。为此提供+1。但是,Label 开始看起来很丑(它的高度和宽度也变大了),所以这对我来说不是一个真正的解决方案 =(
  • 不是我建议你这样做。
【解决方案3】:

这里有一个解决方案(可能不是最好的),可以改写为“带有渐变文本颜色的自动调整标签”。

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

背后的想法很简单:重写 AutoSize 并在 Paint 事件中处理它(所有东西都在一个地方),如果需要的文本大小与 ClientSize 不同 - 调整大小控制(这将导致重绘)。有一件事是你必须在宽度和高度上加上 +1,因为 SizeF 有分数,有时 +1 像素比松散 1 像素更好,而且你的文本不合适。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多