I created a flat Button with a transparent border, also setting FlatAppearance.BorderSize = 0
.
The border is hidden on a mouse click and the Button background uses a custom Color when the Mouse button is pressed.
My problem is that cannot remove the border that is drawn when the Button becomes active, for example pressing the Tab key.
I can't use the TabStop
property (set it to false) because I want the functionalities I've designed.
I just want to paint the background color and hide the border (the same as mouse click colors).
The Button properties in the Form Designer:
this.importBtn.BackgroundImage = global::CompetitionManager.Properties.Resources.Open;
this.importBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.importBtn.Cursor = System.Windows.Forms.Cursors.Hand;
this.importBtn.Delta = 5;
this.importBtn.Dock = System.Windows.Forms.DockStyle.Fill;
this.importBtn.FlatAppearance.BorderSize = 0;
this.importBtn.FlatAppearance.MouseDownBackColor = System.Drawing.Color.SteelBlue;
this.importBtn.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent;
this.importBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.importBtn.ForeColor = System.Drawing.Color.Transparent;
this.importBtn.Location = new System.Drawing.Point(3, 50);
this.importBtn.MoveXDirection = false;
this.importBtn.MoveYDirection = true;
this.importBtn.Name = "importBtn";
this.importBtn.Size = new System.Drawing.Size(183, 162);
this.importBtn.TabIndex = 0;
this.ToolTip.SetToolTip(this.importBtn, "Import Competitors (Excel/XML)");
this.importBtn.UseMargin = true;
this.importBtn.UseVisualStyleBackColor = true;
this.importBtn.Click += new System.EventHandler(this.ImportFile_Click);
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);
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.