2008-09-29 21 views
18

Tengo un par de botones de los cuales modifiqué su apariencia. Los he configurado como botones planos con un fondo y un borde personalizado para que se vean bonitos y nada como los botones normales (en realidad, se parecen ahora a los botones de Office 2003 ;-). Los botones tienen un borde de un píxel.Cómo establecer/cambiar/eliminar el estilo de enfoque en un botón en C#?

Sin embargo, cuando se selecciona el botón (se enfoca mediante un clic o una acción del teclado como presionar la tecla tab) el botón se pone de repente alrededor del mismo color, haciendo que sea un borde de dos píxeles. Además, cuando desactivo el borde de un píxel, el botón no obtiene un borde de un píxel en el foco.

En la red esta pregunta se hace mucho como '¿Cómo puedo desactivar el foco en un botón', pero eso no es lo que quiero: el enfoque debe todavía existir, simplemente no pantalla en la forma que lo hace ahora.

¿Alguna sugerencia? :-)

Respuesta

0

Ciertamente puede dibujar el botón usted mismo. Uno de los indicadores del estado está enfocado.

Por lo tanto, en el evento del sorteo si la bandera está enfocada, avance y dibuje el botón como lo desee; de ​​lo contrario, simplemente páselo al método base.

+0

¿Podría elaborar un poco más, ya que no hay evento * Draw *? Sin embargo, hay un evento Paint, pero no banderas de estado. =) Entiendo y me gusta la idea, solo un poco perdido en la implementación real. –

0

Considere implementar su propio código de dibujo para el botón. De esa forma tienes el control total. En el pasado, implementé mi propio derivado de control que personaliza mi botón e implementa todas las características del botón para mis propósitos, pero usted debería poder anular la pintura del botón y hacerlo usted mismo, controlando así cómo se dibuja en cada estado. , incluso cuando está enfocado.

30

¿Este es el efecto que está buscando?

public class NoFocusCueButton : Button 
{ 
    protected override bool ShowFocusCues 
    { 
     get 
     { 
      return false; 
     } 
    } 
} 

Se puede utilizar esta clase de botón a medida solo como un botón normal, pero no le dará un rectángulo extra en foco.

+2

¡Gracias por la gran sugerencia! Esto elimina un rectángulo de enfoque grisáceo interior, pero no el borde de un píxel añadido (lo que lo convierte en un límite total de dos píxeles). –

+2

@Chris Jester-Young: compruebe la respuesta de Josh Stribling para ocultar el borde adicional de un píxel. – Marc

1

El segundo borde que se agrega es el borde "botón predeterminado" estándar de Windows. Puede haber notado que si recorre la mayoría de los cuadros de diálogo con varios botones (como cualquier ventana de propiedades del Panel de control), el botón original "doble borde" se convierte en "normal" y el botón en foco se convierte en "doble borde". "

Esto no es necesariamente un enfoque en el trabajo, sino más bien una indicación visual de la acción realizada al presionar la tecla Enter.

Suena, para mí, como si realmente no le importara el funcionamiento interno. Desea que la pantalla no tenga dos bordes, totalmente comprensible. El trabajo interno es explicar por qué estás viendo este comportamiento. Ahora ... Para tratar de arreglarlo.

Lo primero que probaría, y tenga en cuenta, no lo he validado, es un truco. Cuando un botón recibe el foco (obteniendo así el borde doble), apague su único borde. Puede obtener el efecto que desea, y es bastante simple. (Enganche en el evento Focus. Mejor aún, subclase Button y anule OnFocus, luego use esa subclase para sus botones futuros).

Sin embargo, eso podría presentar efectos secundarios visuales nuevos e incómodos. En ese sentido, y porque los hacks rara vez son la mejor respuesta, tengo que recomendar "oficialmente" lo que otros han dicho: pintar el botón personalizado. Aunque el código aquí puede ser excesivo, este link at CodeProject explica cómo hacerlo (enlace VB; necesitará traducir). Deberías, en un modo personalizado completo, poder deshacerte por completo de ese segundo borde.

2

Hay otra manera que funciona bien para botones de estilo plano. No use botones sino etiquetas. Como está reemplazando completamente la IU del botón, no importa si utiliza un control de botón o una etiqueta. Simplemente maneje el clic de la misma manera.

Esto funcionó para mí, aunque no es una buena práctica, es un buen truco y siempre y cuando nombre el botón obviamente (y comente la fuente) otros codificadores se darán cuenta de la idea.

Ryan

0

Establecer la propiedad FocusVisualStyle dependencia a nulo en su estilo, y el borde de puntos se habrá ido.

De MSDN: Styling for Focus in Controls, and FocusVisualStyle

de Windows Presentation Foundation (WPF) proporciona dos mecanismos paralelos para que cambian la apariencia visual de un control cuando recibe teclado enfoque. El primer mecanismo es usar definidores de propiedades para propiedades tales como como IsKeyboardFocused dentro del estilo o plantilla que se aplica al control . T El segundo mecanismo es proporciona un estilo separado como el valor de la propiedad FocusVisualStyle; el "estilo visual de enfoque" crea un árbol visual separada para una adorner que se basa en la parte superior del mando, en lugar de cambiar el árbol visual del control u otro elemento de la interfaz de usuario por que lo sustituya. Este tema trata sobre los escenarios donde cada uno de estos mecanismos es apropiado.

El extra fronteras que se ve es definido por el FocusVisualStyle y no en la plantilla de control, por lo que necesita para eliminar o anular el estilo para quitar el borde.

+0

Esto es para WPF, no para Winforms. – DMan

6

Otra opción (aunque un poco hacktastic) es adjuntar un controlador de eventos al evento GotFocus del botón. En ese evento-controlador, pase un valor de False al método NotifyDefault() del botón. Entonces, por ejemplo:

void myButton_GotFocus(object sender, EventArgs e) 
{ 
    myButton.NotifyDefault(false); 
} 

Supongo que esto funcionará siempre, pero no lo he probado extensamente. A mí me funciona por ahora, así que estoy satisfecho con eso.

0

Si usted tiene un cuadro de texto y un botón entonces TextChange caso de cuadro de texto escribir button1.focus();

Se trabajará.

14

hacer un botón personalizado:

public partial class CustomButton: Button 
{ 
    public ButtonPageButton() 
    { 
     InitializeComponent(); 

     this.SetStyle(ControlStyles.Selectable, false); 
    } 
} 

Eso va a deshacerse de esa frontera molesto!;-)

+0

Esto funcionó para mí y fue simple. – theJerm

+0

Desafortunadamente, esto desactiva la capacidad de enfocar el botón. Sobrescribir 'ShowFocusCues' parece mejor. –

-3

he tenido buena suerte simplemente estableciendo la propiedad enfocable del botón que es falsa:

<Button HorizontalAlignment="Left" Margin="0,2" 
     Command="{Binding OpenSuspendedJobCommand, Mode=OneWay}" 
     Focusable="False" 
     Style="{StaticResource ActionButton}" Content="Open Job..." /> 
+1

WPF no es lo mismo que WinForms. – Neolisk

19

tuve el mismo problema con el borde doble molesto, y me encontré con este hilo buscando una respuesta ...

la forma en que esto fue resuelto para establecer el BorderSize a 0 entonces dibujar mi propia frontera, en OnPaint

* Nota: No todo el botón, simplemente la frontera

Un ejemplo sencillo sería:

public class CustomButton : Button 
{ 
    public CustomButton() 
     : base() 
    { 
     // Prevent the button from drawing its own border 
     FlatAppearance.BorderSize = 0; 
     FlatStyle = System.Windows.Forms.FlatStyle.Flat; 
    } 

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

     // Draw Border using color specified in Flat Appearance 
     Pen pen = new Pen(FlatAppearance.BorderColor, 1); 
     Rectangle rectangle = new Rectangle(0, 0, Size.Width - 1, Size.Height - 1); 
     e.Graphics.DrawRectangle(pen, rectangle); 
    } 
} 

En mi caso, esta es la forma en que hice un botón que imita una ToolStripButton, donde la frontera solo es visible cuando coloca el cursor sobre el botón:

public class ToolButton : Button 
{ 
    private bool ShowBorder { get; set; } 

    public ToolButton() 
     : base() 
    { 
     // Prevent the button from drawing its own border 
     FlatAppearance.BorderSize = 0; 

     // Set up a blue border and back colors for the button 
     FlatAppearance.BorderColor = Color.FromArgb(51, 153, 255); 
     FlatAppearance.CheckedBackColor = Color.FromArgb(153, 204, 255); 
     FlatAppearance.MouseDownBackColor = Color.FromArgb(153, 204, 255); 
     FlatAppearance.MouseOverBackColor = Color.FromArgb(194, 224, 255); 
     FlatStyle = System.Windows.Forms.FlatStyle.Flat; 

     // Set the size for the button to be the same as a ToolStripButton 
     Size = new System.Drawing.Size(23, 22); 
    } 

    protected override void OnMouseEnter(EventArgs e) 
    { 
     base.OnMouseEnter(e); 

     // Show the border when you hover over the button 
     ShowBorder = true; 
    } 

    protected override void OnMouseLeave(EventArgs e) 
    { 
     base.OnMouseLeave(e); 

     // Hide the border when you leave the button 
     ShowBorder = false; 
    } 

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

     // The DesignMode check here causes the border to always draw in the Designer 
     // This makes it easier to place your button 
     if (DesignMode || ShowBorder) 
     { 
      Pen pen = new Pen(FlatAppearance.BorderColor, 1); 
      Rectangle rectangle = new Rectangle(0, 0, Size.Width - 1, Size.Height - 1); 
      e.Graphics.DrawRectangle(pen, rectangle); 
     } 
    } 



    // Prevent Text from being set on the button (since it will be an icon) 
    [Browsable(false)] 
    public override string Text { get { return ""; } set { base.Text = ""; } } 

    [Browsable(false)] 
    public override ContentAlignment TextAlign { get { return base.TextAlign; } set { base.TextAlign = value; } } 
} 
0

También puede crear un botón invisible y activarlo siempre que presione otro botón.

Cuestiones relacionadas