通過重寫控件 Paint 事件,使用 GraphicsPath 構建圓角矩形路徑,配合 Pen 繪製,實現任意控件的圓角邊框效果。本文提供可直接復用的核心算法與集成指南。
private void DrawRoundedBorder(Graphics g, Control ctrl) {
float width = ctrl.Width - 1;
float height = ctrl.Height - 1;
float radius = 2f; // 圓角半徑(像素)
// 定義 12 個關鍵點構建圓角矩形
PointF[] points = {
new PointF(radius, 0), // 左上橫邊起點
new PointF(width - radius, 0), // 右上橫邊終點
new PointF(width, radius), // 右上彎曲起點
new PointF(width, height - radius), // 右下彎曲終點
new PointF(width - radius, height), // 右下橫邊終點
new PointF(radius, height), // 左下橫邊起點
new PointF(0, height - radius), // 左下彎曲終點
new PointF(0, radius) // 左上彎曲起點
};
using (GraphicsPath path = new GraphicsPath()) {
path.AddLines(points); // 直線連接,實際為倒角而非真圓弧
// 真圓弧需用 path.AddArc 配合四個角
using (Pen pen = new Pen(Color.FromArgb(150, Color.Blue), 1)) {
pen.DashStyle = DashStyle.Solid;
g.DrawPath(pen, path);
}
}
}
private void DrawTrueRoundedRect(Graphics g, Control ctrl, float radius, Pen pen) {
RectangleF rect = new RectangleF(0, 0, ctrl.Width - 1, ctrl.Height - 1);
using (GraphicsPath path = new GraphicsPath()) {
// 四個圓弧 + 四條直線
path.AddArc(rect.X, rect.Y, radius * 2, radius * 2, 180, 90); // 左上
path.AddArc(rect.Right - radius * 2, rect.Y, radius * 2, radius * 2, 270, 90); // 右上
path.AddArc(rect.Right - radius * 2, rect.Bottom - radius * 2, radius * 2, radius * 2, 0, 90); // 右下
path.AddArc(rect.X, rect.Bottom - radius * 2, radius * 2, radius * 2, 90, 90); // 左下
path.CloseFigure();
g.DrawPath(pen, path);
}
}
Panel、Button、TextBox)ResizeRedraw = true 保證尺寸變化重繪OnPaint 或訂閱 Paint 事件
public class RoundedPanel : Panel {
public float CornerRadius { get; set; } = 8f;
public Color BorderColor { get; set; } = Color.Blue;
public float BorderWidth { get; set; } = 2f;
public RoundedPanel() {
ResizeRedraw = true; // 關鍵!
BackColor = Color.White;
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // 抗鋸齒
using (var pen = new Pen(BorderColor, BorderWidth))
using (var path = GetRoundedRectPath(ClientRectangle, CornerRadius)) {
e.Graphics.DrawPath(pen, path);
}
}
private GraphicsPath GetRoundedRectPath(RectangleF rect, float radius) {
var path = new GraphicsPath();
float d = radius * 2;
path.AddArc(rect.X, rect.Y, d, d, 180, 90);
path.AddArc(rect.Right - d, rect.Y, d, d, 270, 90);
path.AddArc(rect.Right - d, rect.Bottom - d, d, d, 0, 90);
path.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90);
path.CloseFigure();
return path;
}
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
var g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
var rect = ClientRectangle;
float r = CornerRadius;
using (var path = GetRoundedRectPath(rect, r)) {
// 1. 填充背景
using (var brush = new SolidBrush(BackColor))
g.FillPath(brush, path);
// 2. 繪製邊框
using (var pen = new Pen(BorderColor, BorderWidth))
g.DrawPath(pen, path);
// 3. 設置裁剪區域,防止子控件溢出圓角
var oldClip = g.Clip;
g.SetClip(path);
// 此處可調用 base.OnPaint 繪制子控件,或手動繪制文本
g.Clip = oldClip;
}
}
DoubleBuffered = true 減少閃爍GraphicsPath.AddArc 構建真圓角矩形,配合 SmoothingMode.AntiAlias 抗鋸齒,ResizeRedraw=true 保證自適應,封裝為可復用基類即可賦予任意 WinForms 控件圓角外觀。WPF 中直接使用 Border.CornerRadius 更簡潔高效。