2011-05-24 18 views
10

Tengo una aplicación que se utilizará en un sistema de pantalla táctil, y contiene una serie de botones que son bastante grandes (~ 100 píxeles cuadrados).Reducir el relleno alrededor del texto en el botón WinForms

Cada botón tendrá entre 1 y 4 líneas de texto (normalmente una palabra por línea).

Debido a la gran cantidad de relleno en el botón, tengo que reducir el tamaño del texto para que sea casi ilegible, sin embargo, si pude reducir el relleno interno para que el texto se pintara correctamente hasta la frontera, entonces no tendría un problema.

He intentado reducir el relleno del control a cero de la siguiente manera, pero no ayuda.

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

Un ejemplo del problema se muestra a continuación:

Button with broken text

Como se puede ver, hay mucho espacio para la palabra 'Visión general' para encajar en una línea, pero ¿cómo puedo lograr esto sin reducir el tamaño de la fuente? No me gusta la idea de tener que volver a escribir el código de texto de la pintura del control.

Editar: He notado que aumentar el relleno a varios valores de hasta 300, no hace ninguna diferencia en el relleno interno del control. También para información, el botón que estoy usando es un control que he heredado de la clase Windows.Forms.Button, ya que necesito agregar algunas propiedades, sin embargo, no he interferido con ninguno de los métodos del botón.

Respuesta

5

También reemplaza el método OnPaint() del control Button que está heredando y omite llamar a base.OnPaint() y reemplazarlo con su propio código de extracción.

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

Ese sería mi método preferido, sin embargo no es tan simple, ya que el evento de pintura existente se ocupará de la envoltura y el posicionamiento del texto dentro de los límites , de ahí la razón por la que no estoy interesado en seguir por este camino, a menos, por supuesto, que haya algún método fácil para lograrlo. – Bryan

+1

Aceptado, ya que Graphics.DrawString facilita el trabajo de ajuste y colocación del texto. Funciona perfectamente, muchas gracias. – Bryan

+0

Genial, más simple que mi sugerencia y parece que funciona. +1 – Jodrell

3

He creado una exitosa aplicación de automatización de radio en 1998 usando MFC. Lo primero que hicimos fue crear un nuevo conjunto de controles GUI, ya que, por ejemplo, presionar el botón en la pantalla con el dedo lo oscurece, y los botones estándar no son tan elegantes para eso.

fireplay image

Mi consejo sería no ir con derivar el botón del botón estándar de Windows Forms, pero desde el Control y hacer el dibujo a sí mismo. Si se trata del botón simple que presentó, no tendrá mucho que hacer, solo DrawString, y si es un poco más complicado, tendrá un control total sobre él.

+2

Wow, se ve bien :) –

+0

Fue creado por un buen amigo mío: http://studionebo.com/gui.html –

+0

¡Qué diseño, se ve muy bien! El enlace ya no funciona. – JohnSaps

7

No tiene que dibujar todo el botón usted mismo. acaba de salir de la propiedad de texto vacío y asignar el texto a 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

@Bryan - ambas soluciones propuestas por @Henk Roux y @chiper no son perfectos. Primero generamos el botón sin atributos visuales y el segundo nos obliga a agregar un nuevo atributo como OwnerDrawText.

Consulte mi propuesta a continuación. Anulo la propiedad Text para poder usar su parte privada _Text y adjuntar String.Empty justo antes del evento MyBase.OnPaint(e). Esto hace que ese botón se dibuje sin texto. Más tarde reasigné el texto antiguo a la propiedad privada y dibujé cadena yo mismo.Agrego Inflate a Rectangle para hacer que el texto sea más agradable simplemente tocando el borde del botón, sin superponerlo. Mi proposición funciona con cualquier 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# versión:

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 (brush == new SolidBrush(ForeColor)) { 
      using (stringFormat == new StringFormat {Alignment = StringAlignment.Center,LineAlignment = StringAlignment.Center}) { 
       e.Graphics.DrawString(Text, Font, brush, Rectangle.Inflate(ClientRectangle, -2, -2), stringFormat); 
      } 
     } 

    } 

} 
Cuestiones relacionadas