Доброго времени суток.
Столкнулся с такой проблемой, что после добавление в кнопку фотографии она перестаёт правильно работать, и появляются своеобразные баги, я считаю что это связанно с прорисовкой этой самой кнопки, но, не получается решить данную проблему в одиночку, буду очень благодарен любой помощи.
Чтобы было нагляднее я сделал для вас видео, посмотрите его пожалуйста, в замедленной форме, и вы увидите что на левой форме появляется баг, а вот в правой кнопке не какого бага нет...
Ссылка на видео
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Test_Project.SupportClass
{
[DesignerCategory("Code")]
public class button_check : Control
{
private int m_BorderSize = 2;
private int m_ButtonRoundRadius = 15;
private bool IsHighlighted = false;
private bool IsPressed = false;
private Image _image;
private ImageLayout LautsCallBack { get; set; }
public button_check()
{
SetStyle(ControlStyles.Opaque |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
// To be explicit...
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
this.DoubleBuffered = false;
InitializeComponent();
}
private void InitializeComponent()
{
Size = new Size(100, 40);
BackColor = Color.Tomato;
BackColor2 = Color.Tomato;
ButtonBorderColor = Color.Black;
ButtonHighlightColor = Color.Orange;
ButtonHighlightColor2 = Color.OrangeRed;
ButtonHighlightForeColor = Color.Black;
ButtonPressedColor = Color.Red;
ButtonPressedColor2 = Color.Maroon;
ButtonPressedForeColor = Color.White;
}
public ImageLayout LayoutImage
{
get
{
return LautsCallBack;
}
set
{
LautsCallBack = value;
RecreateHandle();
}
}
public Image ImageButtom
{
get
{
return _image;
}
set
{
_image = value;
RecreateHandle();
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
return cp;
}
}
// Invalidate(rect) in Design-Mode to refresh the view
public int BorderSize
{
get => m_BorderSize;
set
{
m_BorderSize = Math.Max(Math.Min(value, 6), 1);
RepaintControl();
}
}
// Set Max = 44, Min = 1 to avoid quirks and exceptions
public int ButtonRoundRadius
{
get => m_ButtonRoundRadius;
set
{
m_ButtonRoundRadius = Math.Max(Math.Min(value, 44), 1);
RepaintControl();
}
}
public override string Text
{
get => base.Text;
set
{
base.Text = value;
RepaintControl();
}
}
// You should Invalidate the Parent also when these change
public Color BorderColor { get; set; } = Color.Tomato;
public Color BackColor2 { get; set; } = Color.Tomato;
public Color ButtonBorderColor { get; set; }
public Color ButtonHighlightColor { get; set; }
public Color ButtonHighlightColor2 { get; set; }
public Color ButtonHighlightForeColor { get; set; }
public Color ButtonPressedColor { get; set; }
public Color ButtonPressedColor2 { get; set; }
public Color ButtonPressedForeColor { get; set; }
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
var foreColor = IsPressed ? ButtonPressedForeColor : IsHighlighted ? ButtonHighlightForeColor : ForeColor;
var backColor = IsPressed ? ButtonPressedColor : IsHighlighted ? ButtonHighlightColor : BackColor;
var backColor2 = IsPressed ? ButtonPressedColor2 : IsHighlighted ? ButtonHighlightColor2 : BackColor2;
var rect = Path.GetBounds();
using (var pen = new Pen(ButtonBorderColor, m_BorderSize))
using (var pathBrush = new LinearGradientBrush(rect, backColor, backColor2, LinearGradientMode.Vertical))
using (var textBrush = new SolidBrush(foreColor))
using (var sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
e.Graphics.FillPath(pathBrush, Path);
if (m_BorderSize > 0) e.Graphics.DrawPath(pen, Path);
if (_image != null)
{
switch (LayoutImage)
{
case ImageLayout.Stretch:
e.Graphics.DrawImage(_image, this.ClientRectangle);
break;
case ImageLayout.Center:
int left = (this.ClientSize.Width - _image.Width) / 2;
int top = (this.ClientSize.Height - _image.Height) / 2;
e.Graphics.DrawImage(_image, left, top);
break;
case ImageLayout.Tile:
using (var texture = new TextureBrush(_image))
{
e.Graphics.FillRectangle(texture, this.ClientRectangle);
}
break;
case ImageLayout.Zoom:
double xr = (double)this.ClientSize.Width / _image.Width;
double yr = (double)this.ClientSize.Height / _image.Height;
if (xr > yr)
{
rect.Width = (int)(_image.Width * yr);
rect.X = (this.ClientSize.Width - rect.Width) / 2;
}
else
{
rect.Height = (int)(_image.Height * xr);
rect.Y = (this.ClientSize.Height - rect.Height) / 2;
}
e.Graphics.DrawImage(_image, rect);
break;
}
}
rect.Inflate(-4, -4);
e.Graphics.DrawString(Text, Font, textBrush, rect, sf);
}
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
IsHighlighted = true;
RepaintControl();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
IsHighlighted = false;
IsPressed = false;
RepaintControl();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
IsPressed = true;
RepaintControl();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
IsPressed = false;
RepaintControl();
}
private void RepaintControl()
{
Parent?.Invalidate(this.Bounds, true);
Invalidate();
}
private GraphicsPath Path
{
get
{
var rect = ClientRectangle;
int scaleOnBorder = -((m_BorderSize / 2) + 2);
rect.Inflate(scaleOnBorder, scaleOnBorder);
return GetRoundedRectangle(rect, m_ButtonRoundRadius);
}
}
private GraphicsPath GetRoundedRectangle(Rectangle rect, int d)
{
var gp = new GraphicsPath();
gp.StartFigure();
gp.AddArc(rect.X, rect.Y, d, d, 180, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y, d, d, 270, 90);
gp.AddArc(rect.X + rect.Width - d, rect.Y + rect.Height - d, d, d, 0, 90);
gp.AddArc(rect.X, rect.Y + rect.Height - d, d, d, 90, 90);
gp.CloseFigure();
return gp;
}
}
}