【发布时间】:2020-07-07 13:17:26
【问题描述】:
一天中的好时光。 我制作了自己的按钮,在那里我做了进一步操作所需的一切。 接下来,我遇到了这个按钮的平滑度,从字面上看完全不适合我,我决定使用DoubleBuffered,添加DoubleBuffered后,我遇到了另一个问题,更多细节你可以在截图中看到。 在应用程序的背景中,我使用了一张图片。 我寻求帮助,因为我无法解决这个问题。
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Test_Project
{
public class Test_Button : Control
{
public Color BackColor2 { get; set; }
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; }
//--------
public int ButtonRoundRadius { get; set; }
//--------
private bool IsHighlighted;
private bool IsPressed;
public Test_Button()
{
Size = new Size(100, 40);
ButtonRoundRadius = 30;
BackColor = Color.Gainsboro;
BackColor2 = Color.Silver;
ButtonBorderColor = Color.Black;
ButtonHighlightColor = Color.Orange;
ButtonHighlightColor2 = Color.OrangeRed;
ButtonHighlightForeColor = Color.Black;
ButtonPressedColor = Color.Red;
ButtonPressedColor2 = Color.Maroon;
ButtonPressedForeColor = Color.White;
//=============
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
DoubleBuffered = true;
}
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
return createParams;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics graph = e.Graphics;
graph.SmoothingMode = SmoothingMode.HighQuality;
graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
graph.Clear(Parent.BackColor);
var foreColor = IsPressed ? ButtonPressedForeColor : IsHighlighted ? ButtonHighlightForeColor : ForeColor;
var backColor = IsPressed ? ButtonPressedColor : IsHighlighted ? ButtonHighlightColor : BackColor;
var backColor2 = IsPressed ? ButtonPressedColor2 : IsHighlighted ? ButtonHighlightColor2 : BackColor2;
using (var pen = new Pen(ButtonBorderColor, 1))
e.Graphics.DrawPath(pen, Path);
using (var brush = new LinearGradientBrush(ClientRectangle, backColor, backColor2, LinearGradientMode.Vertical))
e.Graphics.FillPath(brush, Path);
using (var brush = new SolidBrush(foreColor))
{
var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
var rect = ClientRectangle;
rect.Inflate(-4, -4);
e.Graphics.DrawString(Text, Font, brush, rect, sf);
}
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
IsHighlighted = true;
Parent.Invalidate(Bounds, false);
Invalidate();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
IsHighlighted = false;
IsPressed = false;
Parent.Invalidate(Bounds, false);
Invalidate();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
IsPressed = true;
Parent.Invalidate(Bounds, false);
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
Parent.Invalidate(Bounds, false);
Invalidate();
IsPressed = false;
}
protected GraphicsPath Path
{
get
{
var rect = ClientRectangle;
rect.Inflate(-1, -1);
return GetRoundedRectangle(rect, ButtonRoundRadius);
}
}
public static GraphicsPath GetRoundedRectangle(Rectangle rect, int d)
{
var gp = new GraphicsPath();
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;
}
}
}
【问题讨论】:
-
您没有阅读上一篇文章中描述的大部分内容。您不能在透明控件中使用 DoubleBuffering。它从一开始就违背了目的。
graph.Clear(Parent.BackColor);也适得其反:你的 Parent 有一个位图作为背景,你正在复制它的BackColor,完全不同的东西。InterpolationMode没用。在FillPath之前仍然调用DrawPath:填充路径的抗锯齿会部分覆盖边框,改变它的颜色等。 -
看到这个半透明控件:Translucent circle with text,它实现了我建议的很多东西。