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

问题描述

| 我有一个将在触摸屏系统上使用的应用程序,它包含许多相当大的按钮(约100像素见方)。 每个按钮将包含1到4行文字(通常每行一个字)。 由于按钮中的填充量很大,因此我不得不减小文本的大小,使其几乎变得不可读,但是,如果能够减少内部填充量,以便文本可以正确绘制到边界,那么我不会有问题。 我曾尝试将控件的填充减少到零,如下所示,但这无济于事。
this.Text = _label;
this.Font = new Font(this.Font.FontFamily,(float) _size);
this.Padding = new Padding(0);
该问题的示例如下所示: 如您所见,\'OVERVIEW \'一词在一行中有足够的空间,但是如何在不减小字体大小的情况下实现这一点?我不喜欢必须重写控件的文本绘制代码的想法。 编辑:我注意到,将填充增加到各种值高达300,对控件的内部填充没有影响。另外,作为信息,我正在使用的按钮是我从Windows.Forms.Button类继承的控件,因为我需要添加一些属性,但是我没有干涉任何Button \自己的方法。     

解决方法

您还可以简单地覆盖继承自其的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));
        }
    }
    ,您不必自己绘制整个按钮。 只需将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,new SolidBrush(ForeColor),ClientRectangle,stringFormat);
        }
    }
}
    ,那时,我已经在\ '98使用MFC创建了一个成功的无线电自动化应用程序。我们要做的第一件事是为其创建了一套全新的GUI控件,因为例如,用手指按下屏幕上的按钮会使它模糊,而标准按钮并不是那么花哨。 我的建议不是从标准WinForms按钮派生您的按钮,而是从
Control
开始自己绘制。如果它是像您介绍的按钮那样的简单按钮,那么您将不需要做很多事情,仅是DrawString,而如果它更为复杂,则可以完全控制它。     ,@Bryan-@Henk Roux和@chiper提出的两种解决方案都不完美。首先生成没有任何视觉属性的按钮,其次迫使我们添加新属性,例如
OwnerDrawText
。 见下面我的主张。我重写
Text
属性,以便能够使用其私有部分
_Text
,并在
MyBase.OnPaint(e)
事件之前附加
String.Empty
。这使得该按钮绘制时没有文本。稍后,我将旧文本重新分配给私有财产并自己绘制字符串。我在
Rectangle
上加上
Inflate
,使文本变得更好看,只是触摸按钮的边框,而不是使其重叠。我的主张适用于任何
flatstyle
。 这是两种平面样式中的标准按钮和无填充按钮的比较:标准样式和平面样式
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,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,stringFormat);
            }
        }

    }

}
    ,在兼容的WinForms控件上,您还可以尝试将
UseCompatibleTextRendering
属性设置为
true
。它使用
Graphics
类而不是默认的
TextRenderer
类进行文本呈现。虽然它适用于我的特定应用程序,但您的里程可能会有所不同。 这种方法的至少一个缺点是表观字体大小似乎发生了变化(在我的情况下减小了)。 在此处了解更多信息: https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.forms.label.usecompatibletextrendering?view=netframework-4.8     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...