c# WinForm: Remove or Customize the 'Focus Rectangle' for Buttons
Is there a way to disable or better yet draw your own focus rectangle for a regular button control! (that dotted line seems so Windowss 95ish)
I've noticed that the开发者_运维技巧 control properties (FOR BUTTONS) does not have a ownerdrawfixed setting (which I don't know if that's even the route to use for the solution, although i've seen it used for customizing other controls).
Getting this right is trickier than it sounds. No doubt one of the reasons that custom button painting isn't overridable. This worked as expected:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
class MyButton : Button {
private VisualStyleRenderer renderer;
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
if (this.Focused && Application.RenderWithVisualStyles && this.FlatStyle == FlatStyle.Standard) {
if (renderer == null) {
VisualStyleElement elem = VisualStyleElement.Button.PushButton.Normal;
renderer = new VisualStyleRenderer(elem.ClassName, elem.Part, (int)PushButtonState.Normal);
}
Rectangle rc = renderer.GetBackgroundContentRectangle(e.Graphics, new Rectangle(0, 0, this.Width, this.Height));
rc.Height--;
rc.Width--;
using (Pen p = new Pen(Brushes.DarkGray)) {
e.Graphics.DrawRectangle(p, rc);
}
}
}
}
A quick and easy way to disable the focus rectangle all together is to subclass the control and include this code:
public class CustomButton : Button
{
protected override bool ShowFocusCues
{
get
{
return false;
}
}
}
Just simple way.
Set
button.FlatStyle = Flat;
button.FlatAppearance.BorderColor = Color.FromArgb(0, 255, 255, 255);
button.FlatAppearance.BorderSize = 0;
button.TabStop = false;
FlatAppearance.BorderColor
set on code cause could not transparent color set in design mode.
Subclass the Button class and override OnPaint. If your override does not call base.OnPaint, nothing will be drawn for the button and you will have complete control (including the focus rectangle).
One quick/dirty solution that I found (for removing the focus rectangle only) was explicitly defining the background color. For the default control color, for ex:
this._dropDownButton.BackColor = System.Drawing.ColorTranslator.FromHtml("#F0F0F0");
EDIT: Apparently this doesn't work. It was being fixed in my case for an unrelated reason. Apologies.
I had the same issue when using BackgroundImage
to set an image on the button. When the user pressed 'Tab', my image button got a black rectangle.
The solution that worked for me is:
- Call for NotifyDefault(false) for every button I used.
- Set the
TabStop
property to false for every button I used.
Tested on .NET Framework 4.6.2.
Before:
After:
In my case, I have to use both solutions above to make it work.
public class ButtonNoFocus : Button
{
protected override bool ShowFocusCues
{
get
{
return false;
}
}
public override void NotifyDefault(bool value)
{
base.NotifyDefault(false);
}
}
A simple solution to hide the focus frame would be to switch the focus from buttons to a dummy control as soon as the button has been clicked:
public frmMain()
{
...
RemoveControlFocusFrame(this);
}
private void RemoveControlFocusFrame(Control c)
{
if (c.Controls.Count == 0)
{
if (c is Button || c is CheckBox)
c.GotFocus += (o, e) => lblFocusDump.Focus();
return;
}
foreach (Control sub in c.Controls)
RemoveControlFocusFrame(sub);
}
The dummy lblFocusDump label has its Visible set to true and can be hidden in Designer by pushing it to background behind any other control.
精彩评论