During this time, I made a small project and used a background transparent button that only showed images and text. I did not find a ready-made button. So I wrote one myself, mainly to rewrite the onpaint event.
The code for this button is as follows,
Whether a button is selected indicates whether there is a select status similar to that in the menu after the button is pressed, and whether the two buttons are mutually exclusive at the same level means that when there are multiple buttons in the same space, click whether to cancel the selected status of another button.
/********************** Created By Liushufeng ************ */using System; using System. collections. generic; using System. text; using System. windows. forms; using System. drawing; using System. componentModel; using System. drawing. drawing2D; namespace OurControls {public class OurButton: Label {private bool isMouseIn; private bool isMouseDown; private bool withBorder = true; private bool ro UndCorner = true; private bool withArrow = true; private int intervalBetweenTextAndBorder = 2; private int intervalBetweenTextAndImage = 2; private Color colorMouseIn = Color. white; private Color colorMouseDown = Color. white; private bool haveCheckState = true; private bool exclusion = true; private eTextPosition textPosition = eTextPosition. bottom; [CategoryAttribute ("Text Location"), Browsable (true), Dis PlayName ("Text Location"), DescriptionAttribute ("Text Location")] public eTextPosition TextPosition {get {return textPosition;} set {textPosition = value; this. invalidate () ;}} [CategoryAttribute ("Draw border"), Browsable (true), DisplayName ("Draw border"), DescriptionAttribute ("Draw border")] public bool WithBorder {get {return withBorder;} set {withBorder = value; this. invalidate () ;}} [CategoryAttribute ("rounded corner"), Browsable (tru E), DisplayName ("rounded corner"), DescriptionAttribute ("rounded corner")] public bool RoundCorner {get {return roundCorner;} set {roundCorner = value; this. invalidate () ;}[ CategoryAttribute (""), Browsable (true), DisplayName (" "), descriptionAttribute ("")] public bool WithArrow {get {return withArrow;} set {withArrow = value; this. invalidate () ;}} [CategoryAttribute ("interval between text and image"), Browsable (t Rue), DisplayName ("interval between text and image"), DescriptionAttribute ("interval between text and image")] public int IntervalBetweenTextAndImage {get {return intervalBetweenTextAndImage ;} set {intervalBetweenTextAndImage = value; this. invalidate () ;}} [CategoryAttribute ("interval between text and border"), Browsable (true), DisplayName ("interval between text and border "), descriptionAttribute ("interval between text and border")] public int IntervalBetweenTextAndBorder {get {return intervalBet WeenTextAndBorder;} set {intervalBetweenTextAndBorder = value; this. invalidate () ;}} [CategoryAttribute ("background color when hovering"), Browsable (true), DisplayName ("background color when hovering "), descriptionAttribute ("background Color when hovering")] public Color ColorMouseIn {get {return colorMouseIn;} set {colorMouseIn = value ;}} [CategoryAttribute ("selected background Color "), browsable (true), DisplayName ("selected background color"), DescriptionAttribute ("selected background color")] publ Ic Color ColorMouseDown {get {return colorMouseDown;} set {colorMouseDown = value;} [CategoryAttribute ("whether selected"), Browsable (true ), displayName ("whether selected"), DescriptionAttribute ("whether selected")] public bool CheckState {get {return haveCheckState;} set {haveCheckState = value ;}} [CategoryAttribute (""), Browsable (true), DisplayName (""), DescriptionAttribute ("")] pub Lic bool Exclusion {get {return exclusion;} set {exclusion = value ;}} protected override void OnClick (EventArgs e) {base. onClick (e); if (CheckState) {isMouseDown = true; if (exclusion) {if (this. parent! = Null) {int ctlCount = this. parent. controls. count; for (int I = 0; I <ctlCount; I ++) {object o = this. parent. controls [I]; if (o. getType () = this. getType () {OurButton button = this. parent. controls [I] as OurButton; if (button! = Null) {if (button! = This) {button. popUp () ;}}}}}} private void PopUp () {this. isMouseDown = false; this. invalidate ();} public override bool AutoSize {get {return false;} set {base. autoSize = value ;}} protected override void OnPaint (PaintEventArgs e) {Graphics g = e. graphics; g. smoothingMode = SmoothingMode. highQuality; float imagex = 0; float imagey = 0; float tx = 0; float ty = 0; float txtHeight = 0; float txtWidth = 0; # region draws the background if (isMouseIn | isMouseDown) {Color c = colorMouseIn; if (isMouseDown) {c = colorMouseDown;} int arrowHeight = 7; if (! WithArrow) arrowHeight = 0; Rectangle rect = new Rectangle (0, 0, this. width, this. height-arrowHeight); Rectangle rect2 = new Rectangle (0, 0, this. width-1, this. height-arrowHeight); GraphicsPath path1 = null; GraphicsPath path2 = null; if (roundCorner) {if (withArrow) {path1 = reverse (rect, 10); path2 = GetRoundRectangleWithArrow (rect2, 10);} else {path1 = GetRoundRecta Ngle (rect, 10); path2 = GetRoundRectangle (rect2, 10);} g. fillPath (new SolidBrush (c), path1); if (withBorder) g. drawPath (new Pen (Color. silver, 2), path2);} else {g. fillRectangle (new SolidBrush (c), rect); g. drawRectangle (new Pen (c, 2), rect2) ;}# endregion # region draw text if (this. text! = String. empty) {SizeF sizeoftext = g. measureString (this. text, Font); txtHeight = (float) (sizeoftext. height); txtWidth = (float) (sizeoftext. width); switch (TextPosition) {case eTextPosition. top: tx = (float) (this. width-sizeoftext. width)/2.0); ty = intervalBetweenTextAndBorder; break; case eTextPosition. left: ty = (float) (this. height-sizeoftext. height ()/2.0); tx = intervalBetweenTextAndBo Rder; break; case eTextPosition. right: if (Image = null) tx = this. width-sizeoftext. width-intervalBetweenTextAndBorder; else tx = intervalBetweenTextAndBorder + Image. width + intervalBetweenTextAndImage; ty = (float) (this. height-sizeoftext. height)/2.0); break; case eTextPosition. bottom: if (Image! = Null) ty = intervalBetweenTextAndBorder + intervalBetweenTextAndImage + Image. height; else ty = IntervalBetweenTextAndBorder; tx = (float) (this. width-txtWidth)/2.0); break;} g. drawString (this. text, Font, new SolidBrush (ForeColor), tx, ty) ;}# endregion # region draw Image if (Image! = Null) {switch (TextPosition) {case eTextPosition. top: imagex = (float) (this. width-Image. width)/2.0); imagey = ty + txtHeight + intervalBetweenTextAndImage; break; case eTextPosition. left: imagex = tx + txtWidth + intervalBetweenTextAndImage; imagey = (float) (this. height-Image. height)/2.0); break; case eTextPosition. right: imagex = IntervalBetweenTextAndBorder; imagey = (float) (this. height-Image. height)/2.0); break; case eTextPosition. bottom: imagey = intervalBetweenTextAndBorder; imagex = (float) (this. width-Image. width ()/2.0); break;} g. drawImage (Image, imagex, imagey) ;}# endregion} protected override void OnMouseEnter (EventArgs e) {base. onMouseEnter (e); isMouseIn = true; this. invalidate ();} protected override void OnMouseLeave (EventArgs e) {base. onMouseLeave (e); isMouseIn = false; this. invalidate ();} private GraphicsPath GetRoundRectangle (Rectangle rectangle, int r) {int l = 2 * r; // divide the rounded Rectangle into eight straight lines and arcs, add GraphicsPath gp = new GraphicsPath (); gp. addLine (new Point (rectangle. X + r, rectangle. y), new Point (rectangle. right-r, rectangle. y); gp. addArc (new Rectangle (rectangle. right-l, rectangle. y, l, l), 270F, 90F); gp. addLine (new Point (rectangle. right, rectangle. Y + r), new Point (rectangle. right, rectangle. bottom-r); gp. addArc (new Rectangle (rectangle. right-l, rectangle. bottom-l, l, l), 0F, 90F); gp. addLine (new Point (rectangle. right-r, rectangle. bottom), new Point (rectangle. X + r, rectangle. bottom); gp. addArc (new Rectangle (rectangle. x, rectangle. bottom-l, l, l), 90F, 90F); gp. addLine (new Point (rectangle. x, rectangle. bottom-r), new Point (rectangle. x, rectangle. Y + r); gp. addArc (new Rectangle (rectangle. x, rectangle. y, l, l), 180F, 90F); return gp;} private GraphicsPath GetRoundRectangleWithArrow (Rectangle rectangle, int r) {int l = 2 * r; // divide the rounded rectangle into eight straight lines and arcs and add them to GraphicsPath gp = new GraphicsPath (); gp. addLine (new Point (rectangle. X + r, rectangle. y), new Point (rectangle. right-r, rectangle. y); gp. addArc (new Rectangle (rectangle. right-l, rectangle. y, l, l), 270F, 90F); gp. addLine (new Point (rectangle. right, rectangle. Y + r), new Point (rectangle. right, rectangle. bottom-r); gp. addArc (new Rectangle (rectangle. right-l, rectangle. bottom-l, l, l), 0F, 90F); int miniwidth = 5; int miniheight = 6; // This is the following line, divide it into four portions // gp. addLine (new Point (rectangle. right-r, rectangle. bottom),); // 1 gp. addLine (new Point (rectangle. right-r, rectangle. bottom), new Point (rectangle. width/2 + miniwidth, rectangle. bottom); // 2 gp. addLine (new Point (rectangle. width/2 + miniwidth, rectangle. bottom), new Point (rectangle. width/2, rectangle. bottom + miniheight); // 3 gp. addLine (new Point (rectangle. width/2, rectangle. bottom + miniheight), new Point (rectangle. width/2-miniwidth, rectangle. bottom); // 4 gp. addLine (new Point (rectangle. width/2-miniwidth, rectangle. bottom), new Point (rectangle. X + r, rectangle. bottom); gp. addArc (new Rectangle (rectangle. x, rectangle. bottom-l, l, l), 90F, 90F); gp. addLine (new Point (rectangle. x, rectangle. bottom-r), new Point (rectangle. x, rectangle. Y + r); gp. addArc (new Rectangle (rectangle. x, rectangle. y, l, l), 180F, 90F); return gp ;}} public enum eTextPosition {Top, Left, Right, Bottom ,}}
The following figure shows the button effect: