How to Set/Change/Remove Focus Style on a Button in C#

Remove blue outlining of buttons

Amalgamating the answers from the duplicate question

public class NoFocusCueButton : Button
{
public NoFocusCueButton() : base()
{
InitializeComponent();

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

protected override bool ShowFocusCues
{
get
{
return false;
}
}
}

How to remove focus from a single control?

In your form Load event you can set the focus on some other control.

If you do not want the control to ever get focus via keyboard, you can also set its TabStop property to false.

If you want that the button should not have focus when you open the form, then you need to correct the TabIndex property. The TabIndex property has an integer as value which specifies the order in which the controls get focus when tab key is pressed. If the control has TabIndex set to 0 then change it to some other value.

Check the documentation for TabIndex and TabStop properties on MSDN.

Flat Button Style - Hide border and Focus Cue when the Button is active

As described in the question, the custom control - a Button, here - is showing its standard Focus Cues when it becomes the ActiveControl. The default rendering doesn't appears to fit in, because the Background color is rendered transparent in a specific context, causing the standard Focus Cue to become obnoxious.

▶ The standard Focus Cue rendering is disabled overriding Control.ShowFocusCues to always return false (except when the handle is not yet created).

▶ The NotifyDefault method is also overridden, to avoid a similar effect when the Button is used to open a Windows that becomes active: in this case, the Button is rendered with a border meant as a visual clue that it's the ActiveControl of that Window.

▶ Some properties that define the Button specialization are removed from the PropertyGrid using a custom ControlDesigner, to avoid unwanted tampering with specific defining properties.

Finally, a custom Focus Cue is drawn at the bottom of the Custom Control's ClientRectangle, to give some feedback, otherwise a User would have no clue what the current Button/Control is.

The custom cue is not shown when the Mouse is hovering or the Button is being clicked.

It's an example of a possible custom rendering. Of course you can now paint whatever you want: a different border, background, translucent overlay etc.

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

[ToolboxItem(true)]
[DesignerCategory("code")]
[Designer(typeof(CustomDesigner))]
public class ImportButton : Button
{
private Color m_FocusColor = Color.LightBlue;
private bool m_DrawFocusCue = false;

public ImportButton() {
Cursor = Cursors.Hand;
Image = new Bitmap(Properties.Resources.[SomeImage]);
FlatAppearance.BorderSize = 0;
FlatAppearance.MouseDownBackColor = Color.SteelBlue;
FlatAppearance.MouseOverBackColor = Color.Transparent;
FlatStyle = FlatStyle.Flat;
}

protected override bool ShowFocusCues {
get {
m_DrawFocusCue = !ClientRectangle.Contains(PointToClient(MousePosition));
return !IsHandleCreated;
}
}

public override void NotifyDefault(bool value) => base.NotifyDefault(false);

// Make it public if this value should be customizable
private int FocusBorderSize { get; set; } = 2;

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

if (Focused && m_DrawFocusCue) {
var rect = ClientRectangle;
rect.Inflate(-FocusBorderSize, -FocusBorderSize);
using (var pen = new Pen(FlatAppearance.MouseDownBackColor, FocusBorderSize)) {
e.Graphics.DrawLine(pen, 0, rect.Bottom, rect.Right, rect.Bottom);
}
}
}

protected override void Dispose(bool disposing) {
if (disposing) {
Image?.Dispose();
}
base.Dispose(disposing);
}

public class CustomDesigner : ControlDesigner
{
private static string[] RemovedProperties = new[] {
"AutoEllipsis", "AutoSize", "AutoSizeMode",
"BackColor", "Cursor", "FlatAppearance", "FlatStyle",
"ForeColor", "Text", "TextAlign", "TextImageRelation"
};

public CustomDesigner() { }

protected override void PreFilterProperties(IDictionary properties) {
foreach (string prop in RemovedProperties) {
properties.Remove(prop);
}
base.PreFilterProperties(properties);
}
}
}

C# Window Forms Control Styles, Remove Focus via Style Change

Well, I think I have found sort of a solution. The solution resolves the focus rectangle issue but does not answer the question of what was wrong with the original code posted. This is my understanding of the rectangle issue....please feel free to correct me if I got any of this wrong.

It would appear that there are two types of dashed/dotted rectangles: rectangles that indicate that a control is focused, and rectangles that indicate that a control is the default control. Both of these situation require you to create a custom class for the control In my case the control of interest was a RadioButton. So here is the code:

public class NoFocusRadioButton: RadioButton
{
// ---> If you DO NOT want to allow focus to the control, and want to get rid of
// the default focus rectangle around the control, use the following ...

// ... constructor
public NoFocusRadioButton()
{
// ... removes the focus rectangle surrounding active/focused radio buttons
this.SetStyle(ControlStyles.Selectable, false);
}
}

or use the following:

public class NoFocusRadioButton: RadioButton
{
// ---> If you DO want to allow focus to the control, and want to get rid of the
// default focus rectangle around the control, use the following ...

protected override bool ShowFocusCues
{
get
{
return false;
}
}
}

I am using the first (constructor code) approach to not allow input focus.

This all works great to solve the rectangle problem but I still don't understand why the initial code did not work.

On windows forms, set tab focus to a button

You can use either of these options to set the focus on a control in Load event of the form:

  • this.ActiveControl = this.button1;
  • this.button1.Select();
  • this.Show(); this.button1.Focus();.

You can use the Control.Focus method in the Load event of the form to set the focus on a control only after the Visible property of the form is set to true.

After selection the button, the border of the button will be drawn in a way that shows it's the active control, but the focus cues will not be drawn.

As a quick and dirty fix, you can send a Tab, and a Shift + Tab to your form:

SendKeys.SendWait("{TAB}");
SendKeys.SendWait("+{TAB}");

If you are interested to change the standard behavior of Button to see focus cues when you select button in code or using mouse, you can create your own button inheriting Button and override its ShowFocusCues to return Focused value. You can read more about it here:

public class MyCustomButton : Button
{
protected override bool ShowFocusCues
{
get { return this.Focused; }
}
}

Change backgorund of button in wpf when it has focus

I believe that your problem is caused by the default ControlTemplate for the Button control. The colour animations that you describe are defined in this ControlTemplate and so you need to provide your own ControlTemplate to remove this behaviour:

<Button Content="Click Me" Background="Blue">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter TargetName="Border" Property="Background" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>


Related Topics



Leave a reply



Submit