Cómo establecer / cambiar / eliminar el estilo de enfoque en un botón en C #?

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.

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 de repente se pone y el borde extra alrededor del mismo color, por lo que es 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 es muy parecida a “¿Cómo puedo desactivar el foco en un botón?”, Pero eso no es lo que quiero: el foco aún debe existir , simplemente no se muestra de la manera en que lo hace ahora.

¿Alguna sugerencia? 🙂

¿Es este el efecto que estás buscando?

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

Puede usar esta clase de botón personalizado como un botón normal, pero no le dará un rectángulo adicional en el enfoque.

Tuve el mismo problema con el molesto borde doble y tropecé con este hilo en busca de una respuesta …

La forma en que resolví esto fue establecer BorderSize en 0 y luego dibujar mi propio borde en OnPaint

* Nota: no es el botón completo, solo el borde

Un ejemplo simple 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, así es como hice un botón que imita un ToolStripButton, donde el borde solo es visible cuando pasas 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; } } } 

Haz un botón personalizado:

 public partial class CustomButton: Button { public ButtonPageButton() { InitializeComponent(); this.SetStyle(ControlStyles.Selectable, false); } } 

¡Eso eliminará ese molesto límite! 😉

Otra opción (aunque un poco hacktastic) es adjuntar un controlador de eventos al evento GotFocus del botón. En ese controlador de eventos, 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á todo el tiempo, pero no lo he probado exhaustivamente. A mí me funciona por ahora, así que estoy satisfecho con eso.

Hay otra manera que funciona bien para botones de estilo plano. No use botones sino tags. 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 gran práctica, es un buen truco y siempre y cuando nombre el botón obviamente (y comente la fuente) otros codificadores elegirán la idea.

Ryan

El segundo borde que se agrega es el borde estándar del “botón predeterminado” 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 emprendida al presionar la tecla Enter.

Suena, para mí, como si realmente no te importara ese trabajo 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 futuros botones).

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 enlace en CodeProject analiza cómo hacerlo (enlace VB, necesitarás traducir). Deberías, en un modo personalizado completo, poder deshacerte por completo de ese segundo borde.

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

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

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.

Establezca la propiedad de dependencia FocusVisualStyle en nulo en su estilo, y el borde punteado desaparecerá.

Desde MSDN: Estilo para Focus in Controls y FocusVisualStyle

Windows Presentation Foundation (WPF) proporciona dos mecanismos paralelos para cambiar la apariencia visual de un control cuando recibe el foco del teclado. El primer mecanismo es usar los establecedores de propiedades para propiedades como IsKeyboardFocused dentro del estilo o plantilla que se aplica al control. El segundo mecanismo es proporcionar un estilo separado como el valor de la propiedad FocusVisualStyle; el “estilo visual de enfoque” crea un árbol visual separado para un adorno que dibuja sobre el control, en lugar de cambiar el árbol visual del control u otro elemento de IU mediante su sustitución. Este tema analiza los escenarios donde cada uno de estos mecanismos es apropiado.

El borde adicional que ve está definido por FocusVisualStyle y no en la plantilla de control, por lo que debe eliminar o anular el estilo para eliminar el borde.

Si tiene un cuadro de texto y un botón, en el evento de cambio de texto de la caja de texto, escriba button1.focus();

Funcionará.

También puede crear un botón invisible y hacerlo activo cada vez que presiona otro botón.

He tenido buena suerte meramente estableciendo que la propiedad Focusable del botón sea falsa: