在WinForms按钮中减少文本周围的填充

时间:2011-05-24 07:30:24

标签: .net winforms button fonts paint

我有一个将在触摸屏系统上使用的应用程序,它包含许多相当大的按钮(~100px square)。

每个按钮将有1到4行文本(通常每行一个单词)。

由于按钮中有大量的填充,我不得不缩小文本的大小,使其变得几乎不可读,但是如果我能够减少内部填充,那么文本会正确地绘制到了边境,那我就不会有问题了。

我试图将控件的填充减少到零,如下所示,但它没有帮助。

this.Text = _label;
this.Font = new Font(this.Font.FontFamily, (float) _size);
this.Padding = new Padding(0);

问题的一个例子如下所示:

Button with broken text

正如您所看到的,“OVERVIEW”这个词有足够的空间放在一行上,但是如何在不缩小字体大小的情况下实现这一目标呢?我不喜欢不得不重写控件的文本绘画代码。

编辑:我注意到将填充增加到高达300的各种值,对控件的内部填充没有任何影响。另外,对于信息,我使用的按钮是我从Windows.Forms.Button类继承的控件,因为我需要添加一些属性,但是我没有干涉任何Button自己的方法。 / p>

5 个答案:

答案 0 :(得分:7)

您不必自己绘制整个按钮。 只需将Text属性保留为空,并将文本分配给OwnerDrawText

public class NoPaddingButton : Button
{
    private string ownerDrawText;
    public string OwnerDrawText
    {
        get { return ownerDrawText; }
        set { ownerDrawText = value; Invalidate(); }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        if (string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(ownerDrawText))
        {
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Center;
            stringFormat.LineAlignment = StringAlignment.Center;

            e.Graphics.DrawString(ownerDrawText, Font, new SolidBrush(ForeColor), ClientRectangle, stringFormat);
        }
    }
}

答案 1 :(得分:6)

您还可以简单地覆盖您继承的Button控件的OnPaint()方法,并省略调用base.OnPaint(),并将其替换为您自己的绘图代码。

    protected override void OnPaint(PaintEventArgs pevent)
    {
        //omit base.OnPaint completely...

        //base.OnPaint(pevent); 

        using (Pen p = new Pen(BackColor))
        {
            pevent.Graphics.FillRectangle(p.Brush, ClientRectangle);
        }

        //add code here to draw borders...

        using (Pen p = new Pen(ForeColor))
        {
            pevent.Graphics.DrawString("Hello World!", Font, p.Brush, new PointF(0, 0));
        }
    }

答案 2 :(得分:4)

我在98年使用MFC创建了一个成功的无线电自动化应用程序。我们做的第一件事就是我们为它创建了全新的GUI控件集,因为例如,用手指按下屏幕上的按钮会遮挡它,而标准按钮对它来说并不那么花哨。

fireplay image

我的建议不是从标准的WinForms按钮中获取按钮,而是从Control获取并自己绘制。如果它是你所呈现的简单按钮,你就没有太多事情要做,只是DrawString,如果它有点复杂,你就可以完全控制它。

答案 3 :(得分:2)

@Bryan - @ Henk Roux和@chiper提出的两种解决方案并不完美。首先生成没有任何视觉属性的按钮,然后强制我们添加新属性,如OwnerDrawText

请参阅下面的命题。我重写Text属性,以便能够使用其私有部分_Text并在String.Empty事件之前附加MyBase.OnPaint(e)。这使得该按钮无需文本即可绘制。后来我将旧文本重新分配给私人财产并自己绘制字符串。我将Inflate添加到Rectangle以使文本更好,只需触摸按钮的边框,而不是重叠它。我的命题适用于任何flatstyle

Here is comparison of standard and no padding button in two flatstyles: standard and flat

Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms

Public Class ButtonNoPadding
    Inherits Button

    Private _textCurrent As String
    Private _Text As String

    <Category("Appearance")>
    Public Overrides Property Text() As String
        Get
            Return _Text
        End Get
        Set(ByVal value As String)
            If value <> _Text Then
                _Text = value
                Invalidate()
            End If
        End Set
    End Property

    Protected Overrides Sub OnPaint(e As PaintEventArgs)

        _textCurrent = Text
        _Text = String.Empty
        MyBase.OnPaint(e)
        _Text = _textCurrent

        Using brush = New SolidBrush(ForeColor)
            Using stringFormat = New StringFormat() With {.Alignment = StringAlignment.Center, .LineAlignment = StringAlignment.Center}
                e.Graphics.DrawString(Text, Font, brush, Rectangle.Inflate(ClientRectangle, -2, -2), stringFormat)
            End Using
        End Using

    End Sub

End Class

C#版本:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

public class ButtonNoPadding : Button
{

    private string _textCurrent;

    private string _Text;
    [Category("Appearance")]
    public override string Text {
        get { return _Text; }
        set {
            if (value != _Text) {
                _Text = value;
                Invalidate();
            }
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        _textCurrent = Text;
        _Text = string.Empty;
        base.OnPaint(e);
        _Text = _textCurrent;

        using (var brush = new SolidBrush(ForeColor)) {
            using (var stringFormat = new StringFormat {Alignment = StringAlignment.Center,LineAlignment = StringAlignment.Center}) {
                e.Graphics.DrawString(Text, Font, brush, Rectangle.Inflate(ClientRectangle, -2, -2), stringFormat);
            }
        }

    }

}

答案 4 :(得分:0)

在兼容的WinForms控件上,您还可以尝试将UseCompatibleTextRendering属性设置为true。它使用Graphics类而不是默认的TextRenderer类进行文本呈现。当它适用于我的特定应用程序时,您的里程可能会有所不同。

这种方法的至少一个缺点是表观字体大小似乎发生了变化(在我的情况下减小了)。

在此处了解更多信息: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.label.usecompatibletextrendering?view=netframework-4.8

相关问题