2025-10-31
C#
00

在Windows Forms应用程序中,系统默认的TextBox控件功能相对简单,且样式单一。为了满足现代UI设计的需求,我们需要一个更加灵活、可定制的输入控件。本文将详细介绍如何通过继承UserControl和内置TextBox来创建一个增强版本的文本输入控件BzTextBox

控件特性概览

我们的BzTextBox控件具备以下高级特性:

  • 可自定义边框颜色和大小
  • 支持圆角边框
  • 提供下划线样式
  • 内置占位符文本
  • 密码模式
  • 多行文本支持
  • 灵活的样式属性

关键实现细节

边框绘制

控件最大的亮点在于其自定义边框绘制逻辑。通过重写OnPaint方法,我们实现了多种边框样式:

C#
protected override void OnPaint(PaintEventArgs e) { // 支持圆角边框 if (borderRadius > 1) { // 复杂的圆角路径绘制逻辑 using (GraphicsPath pathBorderSmooth = GetFigurePath(rectBorderSmooth, borderRadius)) { // 边框绘制 } } else { // 普通矩形边框绘制 } }
2025-10-31
C#
00

在 Windows 桌面应用开发中,剪贴板是一个非常有用的功能,它允许用户在不同应用程序之间复制和粘贴数据。在 WinForms 应用程序中,我们可以通过调用 Win32 API 来实现剪贴板操作。本文将详细介绍如何在 WinForms 中进行剪贴板操作,并提供一个完整的示例。

引入命名空间

在开始之前,我们需要引用一些必要的命名空间:

C#
using System; using System.Windows.Forms; using System.Runtime.InteropServices;

Win32 API 声明

我们将使用一些 Win32 API 函数来访问剪贴板,这些函数包括:

  • OpenClipboard
  • CloseClipboard
  • EmptyClipboard
  • SetClipboardData
  • GetClipboardData
  • GlobalAlloc
  • GlobalLock
  • GlobalUnlock

在代码中声明这些 API 函数:

C#
public class ClipboardAPI { // 声明 Win32 API 函数 [DllImport("user32.dll")] public static extern bool OpenClipboard(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool CloseClipboard(); [DllImport("user32.dll")] public static extern bool EmptyClipboard(); [DllImport("user32.dll")] public static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem); [DllImport("user32.dll")] public static extern IntPtr GetClipboardData(uint uFormat); [DllImport("kernel32.dll")] public static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes); [DllImport("kernel32.dll")] public static extern IntPtr GlobalLock(IntPtr hMem); [DllImport("kernel32.dll")] public static extern bool GlobalUnlock(IntPtr hMem); // 定义数据格式 public const uint CF_TEXT = 1; }
2025-10-31
C#
00

🔥 本文将带您深入了解C#中的雪花漂移算法,从原理到实现,从基础到高级应用,全方位解析这一高效的唯一ID生成方案。无论您是初学者还是有经验的开发者,都能从中获得实用价值。

什么是雪花漂移算法?

雪花漂移算法(Snowflake Drift)是Twitter雪花算法(Snowflake)的优化版本,专为解决分布式系统中唯一ID生成的复杂需求而设计。在微服务架构、分布式数据库和高并发系统中,它已成为首选的ID生成方案之一。

相比传统雪花算法的优势

  • 📏 生成ID更短:占用空间更小,利于存储和传输
  • 🚀 性能更高:比传统算法快2-5倍
  • 🔄 支持容器环境自动扩容:适应云原生架构
  • 💻 跨语言兼容:不仅限于C#,还支持Java、Go等多种语言
  • 🔌 灵活部署:可在单机和分布式环境中无缝使用

算法核心解析

ID结构设计

雪花漂移算法的精妙之处在于其ID组成结构。每个生成的ID由三个关键部分构成:

Markdown
|------ 时间戳部分 ------|-- 工作机器ID --|-- 序列号 --|
  1. 时间差值:相对于设定基础时间的毫秒差值
  2. WorkerId:机器或应用的唯一标识符
  3. 序列号:同一毫秒内的自增序列,确保同一时间点的唯一性

关键配置参数

  • WorkerIdBitLength:默认6位,决定了WorkerId的最大值
    • 6位可支持最多64个工作节点(2^6=64)
    • 可根据系统规模调整
  • SeqBitLength:默认6位,决定每毫秒可生成的ID数量
    • 6位可每毫秒生成64个ID(2^6=64)
    • 高并发场景可适当增加
  • BaseTime:基准时间,默认为2020年1月1日
    • 可自定义设置,影响ID的使用寿命

C#实现详解

基础实现示例

首先,我们需要安装Yitter.IdGenerator包:

image.png

2025-10-21
C#
00

在C#中,数组和链表都是用来存储数据集合的结构,但它们在内存分配、性能和用途方面有很大的不同。了解这些差异有助于开发者在不同的情况下做出合适的选择。

数组(Array)

数组是一种基本的数据结构,它可以在内存中连续存储固定数量的元素。在C#中,数组声明后大小是固定的,无法动态改变。

数组的特点

  • 静态结构:一旦声明,大小不可改变。
  • 内存分配:连续的内存块。
  • 性能:快速的随机访问,时间复杂度为O(1)。
  • 插入和删除:效率较低,因为可能需要移动多个元素,平均时间复杂度为O(n)。
  • 内存利用:可能会有内存浪费,如果数组没有完全填满。

数组的示例

C#
int[] numbers = new int[5] { 1, 2, 3, 4, 5 }; // 声明一个大小为5的数组 // 访问数组中的元素 int firstNumber = numbers[0]; // O(1) // 修改数组中的元素 numbers[0] = 10; // O(1) // 遍历数组 foreach (int number in numbers) { Console.WriteLine(number); }

image.png

2025-10-21
C#
00

链表是一种基础且重要的数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。在C#中,链表可以通过内置的LinkedList<T>类来实现,也可以自定义节点类和链表类来实现更复杂的操作。在本文中,我们将介绍如何在C#中执行链表的常见操作:插入、删除和查找。

链表的插入操作

链表的插入操作可以分为三种:在链表的开头插入、在链表的末尾插入和在链表的中间插入。

在链表的开头插入

在链表的开头插入节点是一个简单的操作。使用内置的LinkedList<T>类,我们可以使用AddFirst方法。

C#
LinkedList<int> list = new LinkedList<int>(); list.AddFirst(3); // 链表:3 list.AddFirst(2); // 链表:2 -> 3 list.AddFirst(1); // 链表:1 -> 2 -> 3

image.png