我有一个将在触摸屏系统上使用的应用程序,它包含许多相当大的按钮(~100px square)。
每个按钮将有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自己的方法。 / p>
答案 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控件集,因为例如,用手指按下屏幕上的按钮会遮挡它,而标准按钮对它来说并不那么花哨。
我的建议不是从标准的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
类进行文本呈现。当它适用于我的特定应用程序时,您的里程可能会有所不同。
这种方法的至少一个缺点是表观字体大小似乎发生了变化(在我的情况下减小了)。