2025-10-14
C#
00

在Windows窗体应用程序开发中,我们经常需要展示圆形的图片,比如用户头像等。本文将详细介绍如何通过继承PictureBox控件,使用GDI+技术来实现一个支持渐变边框的圆形图片控件。

控件特性

  • 支持圆形显示图片
  • 可自定义边框粗细
  • 支持双色渐变边框
  • 可调整渐变角度
  • 支持多种边框线型
  • 具有抗锯齿效果

完整代码实现

C#
using System; using System.Collections.Generic; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppControls { public class CircularPictureBox : PictureBox { private int borderSize = 2; private Color borderColor = Color.RoyalBlue; private Color borderColor2 = Color.HotPink; private DashStyle borderLineStyle = DashStyle.Solid; private DashCap borderCapStyle = DashCap.Flat; private float gradientAngle = 50F; public CircularPictureBox() { this.Size = new Size(100, 100); this.SizeMode = PictureBoxSizeMode.StretchImage; this.BackColor = Color.Transparent; } // 优化双缓冲设置 protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true); } public int BorderSize { get { return borderSize; } set { borderSize = value; this.Invalidate(); } } public Color BorderColor { get { return borderColor; } set { borderColor = value; this.Invalidate(); } } public Color BorderColor2 { get { return borderColor2; } set { borderColor2 = value; this.Invalidate(); } } public DashStyle BorderLineStyle { get { return borderLineStyle; } set { borderLineStyle = value; this.Invalidate(); } } public DashCap BorderCapStyle { get { return borderCapStyle; } set { borderCapStyle = value; this.Invalidate(); } } public float GradientAngle { get { return gradientAngle; } set { gradientAngle = value; this.Invalidate(); } } protected override void OnResize(EventArgs e) { base.OnResize(e); this.Size = new Size(this.Width, this.Height); } protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); Rectangle rectSurface = this.ClientRectangle; Rectangle rectBorder = Rectangle.Inflate(rectSurface, -borderSize, -borderSize); int smoothSize = 2; if (borderSize > 0) smoothSize = borderSize; using (GraphicsPath pathSurface = GetCirclePath(rectSurface)) using (GraphicsPath pathBorder = GetCirclePath(rectBorder)) using (Pen penSurface = new Pen(this.Parent.BackColor, smoothSize)) { // 设置绘图品质 pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // 设置区域 this.Region = new Region(pathSurface); // 绘制图片 if (this.Image != null) { using (TextureBrush textureBrush = new TextureBrush(this.Image)) { textureBrush.WrapMode = WrapMode.Clamp; // 配置图片缩放 Matrix matrix = new Matrix(); if (this.SizeMode == PictureBoxSizeMode.Zoom) { float scale = Math.Min((float)this.Width / this.Image.Width, (float)this.Height / this.Image.Height); float x = (this.Width - (this.Image.Width * scale)) / 2; float y = (this.Height - (this.Image.Height * scale)) / 2; matrix.Translate(x, y); matrix.Scale(scale, scale); } else { matrix.Scale((float)this.Width / this.Image.Width, (float)this.Height / this.Image.Height); } textureBrush.Transform = matrix; pe.Graphics.FillPath(textureBrush, pathSurface); } } // 绘制表面边缘 pe.Graphics.DrawPath(penSurface, pathSurface); // 绘制边框 if (borderSize >= 1) { using (LinearGradientBrush borderGColor = new LinearGradientBrush( rectBorder, borderColor, borderColor2, gradientAngle)) using (Pen penBorder = new Pen(borderGColor, borderSize)) { penBorder.DashStyle = borderLineStyle; penBorder.DashCap = borderCapStyle; penBorder.Alignment = PenAlignment.Center; pe.Graphics.DrawPath(penBorder, pathBorder); } } } } private GraphicsPath GetCirclePath(Rectangle rect) { GraphicsPath path = new GraphicsPath(); path.AddEllipse(rect); return path; } } }

image.png

2025-10-14
C#
00

在WinForm开发中,默认的CheckBox控件外观比较单调。通过继承CheckBox类并重写OnPaint方法,我们可以使用GDI+绘制出更加美观的自定义CheckBox控件。

完整代码实现

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppControls { public class ModernCheckBox : CheckBox { // 定义三种状态的颜色 private Color checkedColor = Color.MediumSlateBlue; private Color unCheckedColor = Color.Gray; private Color indeterminateColor = Color.RosyBrown; #region 属性 // 选中状态颜色 public Color CheckedColor { get => checkedColor; set { checkedColor = value; Invalidate(); } } // 未选中状态颜色 public Color UnCheckedColor { get => unCheckedColor; set { unCheckedColor = value; Invalidate(); } } // 不确定状态颜色 public Color IndeterminateColor { get => indeterminateColor; set { indeterminateColor = value; Invalidate(); } } #endregion public ModernCheckBox() { // 设置控件最小高度 MinimumSize = new Size(0, 21); // 启用三态选择 this.ThreeState = true; } protected override void OnPaint(PaintEventArgs pevent) { // 获取绘图上下文 Graphics graphics = pevent.Graphics; // 设置抗锯齿模式 graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // 定义复选框的尺寸参数 float borderSize = 18F; // 外边框大小 float checkSize = 12F; // 选中标记大小 float indeterminateHeight = 2F; // 不确定状态线条高度 // 创建外边框矩形 RectangleF borderRect = new RectangleF() { X = 0.5F, Y = (Height - borderSize) / 2, // 垂直居中 Width = borderSize, Height = borderSize }; // 创建选中标记矩形 RectangleF checkRect = new RectangleF() { X = borderRect.X + ((borderRect.Width - checkSize) / 2), Y = (Height - checkSize) / 2, Width = checkSize, Height = checkSize }; // 创建不确定状态矩形 RectangleF indeterminateRect = new RectangleF() { X = borderRect.X + 4, Y = (Height - indeterminateHeight) / 2, Width = borderSize - 8, Height = indeterminateHeight }; // 使用using语句确保资源正确释放 using (Pen borderPen = new Pen(checkedColor, 1.6F)) using (SolidBrush checkBrush = new SolidBrush(checkedColor)) using (SolidBrush indeterminateBrush = new SolidBrush(indeterminateColor)) using (SolidBrush textBrush = new SolidBrush(ForeColor)) { // 清除背景 graphics.Clear(BackColor); // 根据CheckState绘制不同状态 switch (CheckState) { case CheckState.Checked: // 绘制选中状态 graphics.DrawRectangle(borderPen, borderRect.X, borderRect.Y, borderRect.Width, borderRect.Height); graphics.FillRectangle(checkBrush, checkRect); break; case CheckState.Indeterminate: // 绘制不确定状态 borderPen.Color = indeterminateColor; graphics.DrawRectangle(borderPen, borderRect.X, borderRect.Y, borderRect.Width, borderRect.Height); graphics.FillRectangle(indeterminateBrush, indeterminateRect); break; case CheckState.Unchecked: // 绘制未选中状态 borderPen.Color = unCheckedColor; graphics.DrawRectangle(borderPen, borderRect.X, borderRect.Y, borderRect.Width, borderRect.Height); break; } // 绘制文本 graphics.DrawString(Text, Font, textBrush, borderSize + 8, // 文本位置X坐标 (Height - TextRenderer.MeasureText(Text, Font).Height) / 2 // 文本垂直居中 ); } } protected override void OnResize(EventArgs e) { base.OnResize(e); // 根据文本自动调整控件宽度 Width = TextRenderer.MeasureText(Text, Font).Width + 30; } // 添加鼠标悬停效果 protected override void OnMouseEnter(EventArgs eventargs) { base.OnMouseEnter(eventargs); this.Cursor = Cursors.Hand; } protected override void OnMouseLeave(EventArgs eventargs) { base.OnMouseLeave(eventargs); this.Cursor = Cursors.Default; } } }

image.png

2025-10-14
C#
00

概述

AWS API Gateway的安全验证是保护API接口不被非法访问的重要机制。本文将详细介绍如何使用C#实现AWS API的签名验证过程(AWS Signature Version 4)。

image.png

核心组件

主要类结构

  • ApiClient: 负责构造和发送HTTP请求
  • AWS4RequestSigner: 处理AWS签名计算的核心类

关键参数

C#
private const string AccessKey = "YOUR_ACCESS_KEY"; private const string SecretKey = "YOUR_SECRET_KEY"; private const string Region = "cn-northwest-1"; private const string Service = "execute-api";
2025-10-14
C#
00

在 .NET 9 中,System.Text.Json 库得到了显著增强,为开发者提供了更强大和灵活的 JSON 处理能力。这些改进主要集中在 JSON 架构支持、智能应用功能以及序列化和反序列化过程的自定义选项上。本文将详细介绍这些新特性,并提供示例代码,帮助开发者更好地理解和应用这些功能。

JSON 架构导出器

在 .NET 9 中,新增了 JsonSchemaExporter 类,使开发者能够从 .NET 类型中提取 JSON 架构文档。这一特性有助于验证和文档化 JSON 数据结构,确保应用程序之间的一致性。

示例代码

C#
using System.Text.Json; using System.Text.Json.Schema; namespace AppTextJson { public class Employee { public int Id { get; set; } public string Name { get; set; } public string Position { get; set; } } internal class Program { static void Main(string[] args) { var options = new JsonSerializerOptions { WriteIndented = true }; string jsonSchema = JsonSerializer.Serialize(new Employee(), options); Console.WriteLine(jsonSchema); Console.ReadKey(); } } }

输出示例

image.png

2025-10-14
C#
00

在日常的Windows应用开发中,标准的ComboBox控件往往显得过于单调和缺乏个性。作为一名开发者,您是否曾经希望能够:

  • 为每个下拉选项设置独特的背景色
  • 为选项添加个性化图标
  • 精细控制文字颜色和样式

今天,我将为您详细解析如何使用C#开发一个功能强大且高度定制的下拉菜单控件!

关键技术:重写绘制方法

通过重写OnDrawItem方法,我们可以完全自定义每个选项的渲染效果:

  1. 绘制独特背景色
  2. 精确放置图标
  3. 自定义文字样式
  4. 添加选中状态特效

控件特性

  • 支持为每个Item设置独立的背景颜色
  • 支持为每个Item设置独立的文字颜色
  • 支持为每个Item添加图标
  • 支持自定义Item高度
  • 支持鼠标悬停效果
  • 完整的事件处理机制