news 2026/9/28 21:09:29

WinForms TextBox水印自绘控件:从Placeholder到防截图

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WinForms TextBox水印自绘控件:从Placeholder到防截图

简介:面向Winform开发者的文本框水印实现资源,针对原生TextBox缺少placeholder占位提示的痛点,提供基于自定义控件与重写TextBox类的完整解决方案。资源通过继承System.Windows.Forms.TextBox,重写OnPaint方法并配合GotFocus、LostFocus与TextChanged事件,实现输入为空时显示灰色提示文字、获得焦点或开始输入后自动隐藏的效果。压缩包共25个文件,整体仅44KB,包含C#源码文件、项目配置文件、resx/resources资源文件以及编译好的exe可执行程序,目录结构清晰,既可直接运行查看效果,也可打开工程逐行学习。已有254人学习下载,适合有一定Winform基础、希望掌握控件封装技巧的初中级开发者。内容涵盖水印绘制原理、文本变化刷新逻辑、焦点状态处理等核心知识点,并附完整示例与可运行程序。开发者可参照源码自行调整水印文本、颜色和绘制样式,还能进一步扩展多语言支持、自定义字体等高级功能,便于在实际项目中快速集成。

1. 给 WinForms 的 TextBox 加水印:先分清“提示文字”和“防截图水印”

在 WinForms 项目里给 TextBox 加一行浅灰色的“请输入账号”提示,看起来是几分钟的小事,但原生控件并没有 Watermark 属性。很多老项目里,产品和 UI 把这类提示统称为“水印”,于是 textbox 水印、winform 水印的搜索隔三差五就会出现一次。严格说,文本框水印要分成两种:一种是在输入框为空且未聚焦时显示的引导文案,专业叫法 Placeholder;另一种是平铺在整个窗口上的防截图水印。前者用第 3 章的自绘控件解决,后者用第 6 章的最小方案兜底。适合往下读的人,是正在维护原生 WinForms 客户端、需要在界面美化中交付一个不闪烁、能改颜色、能适配密码框的水印文本框的开发者。如果你已经在用第三方控件库,先看库自带的 NullText 或 Placeholder 属性,不必重复造轮子。

2. WinForm 文本框水印的三条实现路线:SendMessage、透明 Label 和自绘控件,别选错

2.1 先回答“你口中的水印是哪一种”

需求来源不同,技术方案完全不同。第一类是引导文案,也就是 TextBox 空着没聚焦时浮现的浅色提示,属于 Placeholder;第二类是安全水印,用多行多列文字盖住主界面,用来防截图泄密。

常见做法是先问一句:这个水印是给谁看的?如果目标是引导用户输入账号密码,那要求是 30 分钟内做完、不闪烁、样式可调;如果目标是防截图,那要求是拍照时能看清、平时不干扰操作。这两条路没有任何共享代码,选错一次就要推倒重来。我在实际项目里见过把 Placeholder 做成全局防截图水印的翻车现场,也见过给安全水印加了“输入后消失”逻辑的尴尬版本。

所以动手前先落一句话需求:什么条件下显示、什么条件下消失、谁可见、颜色是否固定。这句话定了,路线也就定了。

2.2 路线一:EM_SETCUEBANNER,5 行 API 的能行与不行

第一类需求里最简单的方式是给原生 EDIT 控件发 EM_SETCUEBANNER 消息。WinForms 的 TextBox 本质包装了系统 EDIT,而 Windows 从 Vista 开始(ComCtl32 v6)给 EDIT 提供了 cue banner 能力,也就是系统搜索框里见到的淡灰色提示文字。

using System; using System.Runtime.InteropServices; using System.Windows.Forms; public static class TextBoxWatermark { private const int EM_SETCUEBANNER = 0x1501; [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, string lParam); public static void SetWatermark(TextBox textBox, string watermarkText) { // wParam 传 1 表示显示 cue banner,传 0 表示移除 SendMessage(textBox.Handle, EM_SETCUEBANNER, (IntPtr)1, watermarkText); } }

这段代码的逻辑很简单:把控件句柄、消息编号、显示标志和提示文案依次传给系统。参数里唯一要留意的是第一个参数,必须是 TextBox 已经创建好的 Handle。你如果在 Form_Load 里直接调用,此时访问 Handle 属性会强制创建句柄,一般能跑通;更稳的做法是重写 TextBox 的 OnHandleCreated。

这条路线能解决 80% 的登录框需求:原生渲染、无闪烁、默认就是灰色、字号自动跟随控件。但它有三个边界:颜色不支持自定义,样式被系统锁定;PasswordChar 场景在部分 Windows 版本上显示异常;RichTextBox 完全没有 cue banner 能力。内部工具和原型验证用它很合适,对外交付的界面美化项目就得继续往下看。

2.3 路线二:透明 Label,看起来快,做起来全是坑

第二种做法是把一个 Label 叠在 TextBox 上,设置 AutoSize、ForeColor 为浅灰,初始 Visible 为 true,TextChanged 或 Enter 事件里切换 Visible。这种做法胜在零代码量,新手最容易踩进去。

坑在三个地方:WinForms 的 Label 透明是假透明,它把父窗体背景“画”到自己身上,一旦 TextBox 背景色和父窗体不一致,立刻出现一块色斑;点击事件会落在 Label 上,必须给 Label 挂 Click 事件把焦点转给 TextBox;多行 TextBox 或滚动条出现后,Label 的位置和大小很难与内部内容区对齐。

我一般只拿它做界面原型演示,不放进交付代码。真正要长期维护的 winform 项目案例里,这种叠加方案过两个月就会被“水印不见了”或“背景色盖不住”的 bug 找上门。

2.4 路线三:自绘控件,WinForms 界面美化的正解

第三种路线是继承 TextBox 自己画提示文字,这也是 WinForms 界面美化里水印控件的主流做法。实现成本比 API 多 40 到 60 行,换来的是全套控制权:WatermarkText、WatermarkColor、字体、对齐方式、多行、密码框、聚焦时是否显示,全部自己定义。

自绘的难点在于绘制的时机和图层。TextBox 是原生 EDIT 控件,直接重写 OnPaint 需要打开 UserPaint 风格,而 UserPaint 会破坏原生编辑光标和选中状态。正确的常见做法是重写 WndProc,在原生绘制完成之后再叠一层水印文字。第 3 章给完整实现。

顺带说一句,如果你新项目已经落在 WPF 或 .NET MAUI 上,WPF 可以用 Style 加 Trigger 实现水印,MAUI 的 Entry/Editor 更是内置 Placeholder 属性;只有原生 WinForms 用户才需要纠结这个自定义控件。

2.5 选型结论

场景推荐路线理由
内部工具、原型验证EM_SETCUEBANNER代码最少,原生渲染
对外演示、临时方案EM_SETCUEBANNER 或 Label快速能看到效果
正式交付、界面美化自绘 WndProc 控件颜色、字体、密码框、多行都可控
多行或 RichTextBox自绘控件API 和 Label 都覆盖不了

如果项目里已经在用 DevExpress、Telerik 这类控件库,优先看库自带属性,不要和厂商的渲染管线抢绘制权。

3. 自绘 WatermarkTextBox 控件:可直接抄的完整代码与参数说明

3.1 推荐写法:重写 WndProc 而不是 OnPaint

先给一个可以直接放进项目的完整控件。核心思路是在 WndProc 里先调用 base.WndProc 让原生 EDIT 完成输入、光标、选中状态的绘制,然后再用 TextRenderer 把水印文字叠在最上层。

using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace WinFormWatermark.Controls { public class WatermarkTextBox : TextBox { private const int WM_PAINT = 0x000F; private string _watermarkText = "请输入内容"; private Color _watermarkColor = Color.FromArgb(160, 160, 160); private bool _showWhenFocused; private TextFormatFlags _textFormat = TextFormatFlags.Left | TextFormatFlags.VerticalCenter; [Browsable(true)] [Category("水印")] [Description("文本框为空且未聚焦时显示的文字")] public string WatermarkText { get => _watermarkText; set { _watermarkText = value; Invalidate(); } } [Browsable(true)] [Category("水印")] public Color WatermarkColor { get => _watermarkColor; set { _watermarkColor = value; Invalidate(); } } [Browsable(true)] [Category("水印")] [Description("聚焦时仍然显示水印,默认 false")] public bool ShowWhenFocused { get => _showWhenFocused; set { _showWhenFocused = value; Invalidate(); } } [Browsable(true)] [Category("水印")] [Description("水印对齐方式,多行请改用 Top | Left")] public TextFormatFlags WatermarkTextFormat { get => _textFormat; set { _textFormat = value; Invalidate(); } } public WatermarkTextBox() { // 不要设置 UserPaint,保持原生 EDIT 自绘 this.Font = new Font("微软雅黑", 9F); } protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == WM_PAINT) { bool showByFocus = ShowWhenFocused || !Focused; if (string.IsNullOrEmpty(Text) && showByFocus) { using (Graphics g = CreateGraphics()) { Rectangle rect = new Rectangle(2, 2, ClientSize.Width - 4, ClientSize.Height - 4); TextRenderer.DrawText( g, _watermarkText, Font, rect, _watermarkColor, BackColor, WatermarkTextFormat); } } } } } }

这段代码有四个关键点。第一,WndProc 里先 base 后绘制,保证水印永远在原生内容之上,不会盖住输入光标。第二,WM_PAINT 是最低优先级消息,窗口拖拽、内容变化、焦点切换都会触发重绘,水印消失和出现的响应点是正确的。第三,WatermarkTextFormat默认是居左垂直居中,适合单行 TextBox;多行时客户端区域变高,垂直居中会把文字画到整个控件中间,需要改成TextFormatFlags.Left | TextFormatFlags.Top。第四,绘制矩形比 ClientRectangle 内缩了 2 像素,避免水印和系统边框贴在一起。

你还可能注意到代码里没有打开ControlStyles.UserPaint。这是有意为之:SetStyle(UserPaint) 会让 EDIT 控件进入不完全自绘状态,光标、选中背景、系统边框全部可能出现异常,这是 WinForms 水印控件最容易翻车的点。

3.2 另一种写法:UserPaint + OnPaint 的代价

网上还有不少方案是重写 OnPaint,为了让 OnPaint 被触发,先调用 SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true),然后在 OnPaint 里 base.OnPaint 再叠文字。

public class PaintWatermarkTextBox : TextBox { public PaintWatermarkTextBox() { SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (string.IsNullOrEmpty(Text) && !Focused) { TextRenderer.DrawText( e.Graphics, "请输入内容", Font, ClientRectangle, Color.Gray, BackColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter); } } }

这段代码在不少博客里能搜到,但真机表现会暴露问题:光标变成扁块、选中背景颜色异常、边框绘制不均匀。原因就是 UserPaint 让原生 EDIT 放弃了部分自绘职责,而 base.OnPaint 并不会完整补回。我一般不建议对 TextBox 使用这条路线,除非你已经准备好自己处理边框和光标。

3.3 接入现有 WinForm 项目的两个小细节

接入方式很简单,在窗体里声明控件实例或直接拖入工具箱都行。

this.txtAccount.WatermarkText = "请输入账号"; this.txtAccount.WatermarkColor = Color.FromArgb(180, 180, 180); this.txtAccount.Font = new Font("微软雅黑", 10F); this.txtAccount.WatermarkTextFormat = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;

两个细节值得注意。第一,属性修改后已经调用了 Invalidate,不需要额外刷新;但如果控件 Handle 还没创建,Invalidate 是安全的,它会记录一个无效区域,等句柄创建后的下一次绘制自动按新值画。第二,不想在代码里写死文案时,可以在设计器属性面板里直接编辑 WatermarkText,因为上面加了 Browsable 和 Category 特性,属性面板能正常显示“水印”分组。

4. 把水印控件做成交付级:密码框、多行、RichTextBox 和 5 个可调参数

4.1 密码框水印:判空逻辑别用 IsNullOrWhiteSpace

密码框的水印表现和普通文本框没有区别:Text 为空时显示“请输入密码”,输入后显示掩码圆点。真正要注意的是判空逻辑。第 3 章的控件用的是string.IsNullOrEmpty(Text),只要用户敲了任意字符,哪怕是一个空格,水印都会消失,这是符合预期交互的。

如果你顺手改成string.IsNullOrWhiteSpace(Text),用户输入空格时水印仍然挂在那里,视觉上像是密码框坏了。这个差别很隐蔽,自测时不容易发现。另外,PasswordChar 和 UserPaint 有冲突,如果某份代码里同时设置了 PasswordChar 又开了 UserPaint,掩码圆点可能和水印同时出现,这属于 5.2 说的光标绘制异常的同源问题。

4.2 多行文本框水印:VerticalCenter 会让文字漂到中间

多行 TextBox 的 ClientRectangle 高度会被内容撑开,默认的 VerticalCenter 会把水印画在整个控件的垂直中心。一个三行高的输入框,水印会出现在第二行位置,看起来像是提示文字错位。

this.txtRemark.Multiline = true; this.txtRemark.Height = 120; this.txtRemark.WatermarkText = "请输入备注,最多 200 字"; this.txtRemark.WatermarkTextFormat = TextFormatFlags.Left | TextFormatFlags.Top;

对齐改成左上之后,还要处理滚动条:多行加滚动条再滚动内容时,水印的位置不会跟着内容动,但绘制区域本身不变,滚动后如果不重绘,水印会和文字重叠。常见做法是拦截 WM_VSCROLL 和 WM_HSCROLL 后调用 Invalidate,让滚动结束后强制重绘一次。这个处理统一放在 WndProc 里即可。

4.3 RichTextBox 水印:EM_GETRECT 决定绘制区域

RichTextBox 没有 EM_SETCUEBANNER 支持,自绘时它的内容区也不是整个 ClientRectangle,而是由 EM_GETRECT 返回的一个内边距区域。直接用 ClientRectangle 画,水印会踩在边框和滚动条附近。

using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; public class WatermarkRichTextBox : RichTextBox { private const int EM_GETRECT = 0x00B2; private const int WM_PAINT = 0x000F; [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; } [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref RECT lParam); public string WatermarkText { get; set; } = "请输入内容"; protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == WM_PAINT && string.IsNullOrEmpty(Text) && !Focused) { RECT rect = new RECT(); SendMessage(Handle, EM_GETRECT, IntPtr.Zero, ref rect); Rectangle bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); using (Graphics g = CreateGraphics()) { TextRenderer.DrawText(g, WatermarkText, Font, bounds, Color.Gray, BackColor, TextFormatFlags.Left | TextFormatFlags.Top); } } } }

这里 WndProc 的总体结构和 TextBox 版本一致,区别只在取绘制矩形的方式。EM_GETRECT 返回的是控件工作区里真正用于排版文字的区域,水印画进去正好落在第一行文字的位置。注意 RichTextBox 的边框样式如果是 FixedSingle,这个矩形会比 ClientRectangle 小一圈,别再把 2 像素内缩叠加进去了。

4.4 BorderStyle=None 后,水印与自定义圆弧边框怎么共存

WinForms 界面美化里经常把 TextBox 的 BorderStyle 设为 None,再自己画圆角边框。这时第 3 章的控件完全兼容:水印绘制用的是 ClientRectangle,去除系统边框不影响它。

常见做法是先让 UI 层控件把背景画成圆角矩形,再叠加一个 WatermarkTextBox 作为输入层。圆角裁剪可以用 Region 或 GraphicsPath 实现,水印文字照常按 WatermarkTextFormat 绘制,两者互不干扰。如果你看过“winform 自定义圆弧文本框 带图片”这类案例,本质就是把背景图或图片画到底层 Panel,输入框只负责透明背景加水印文字。

4.5 水印控件的 5 个必调参数

参数类型默认值说明
WatermarkTextstring“请输入内容”水印文案,为空则不显示
WatermarkColorColorColor.FromArgb(160,160,160)建议用灰色系,和正常输入文字拉开对比
WatermarkTextFormatTextFormatFlagsLeft | VerticalCenter单行用 VerticalCenter,多行用 Top | Left
ShowWhenFocusedboolfalse聚焦后隐藏;密码框如需要提示可设 true
FontFont微软雅黑 9F继承 TextBox.Font,修改时水印同步变化

这五个参数基本覆盖了日常需求。实际项目里我通常只改 WatermarkText、WatermarkColor 和 TextFormat,剩下的保持默认。如果产品要求水印右侧对齐,比如金额输入框,把 WatermarkTextFormat 改成 Right | VerticalCenter 即可。

5. 文本框水印避坑指南:残影、光标遮挡、输入法闪烁与滚动漂移

5.1 水印有残影或重影

先说现象:窗口被拖拽或 TextBox 频繁重绘时,水印文字边缘出现淡淡的重影,好像上一帧没有擦干净。

根因是 WM_PAINT 里 base 先画了内容,随后用 CreateGraphics 又画一遍,而第二次绘制使用的 DC 与系统擦除背景的时机对不上,旧的像素残留。解决方式是在 WndProc 里对 WM_ERASEBKGND 做处理,控制擦除行为。我一般用 BufferedGraphics 把两段绘制合并,或者直接在 WM_ERASEBKGND 时返回 1,让系统不要额外擦背景。

private const int WM_ERASEBKGND = 0x0014; protected override void WndProc(ref Message m) { if (m.Msg == WM_ERASEBKGND) { // 返回 1 表示背景已由我们处理,避免重复擦除产生残影 m.Result = (IntPtr)1; return; } base.WndProc(ref m); }

这段处理放在水印控件里不影响原生输入绘制。加了之后如果背景没有正确更新,再把 Drawing2D 的 GraphicsPath 绘制逻辑检查一遍。

5.2 光标被水印盖住或消失

这是把 UserPaint 打开后最常见的翻车现场:水印确实出来了,但输入时光标变成一个扁块甚至完全看不见,选中文字的底色也异常。根因是 UserPaint 让原生 EDIT 不再完整自绘,base.OnPaint 又不负责编辑光标。

解决:不要对 TextBox 打开 UserPaint,回到第 3 章的 WndProc 方案。如果你已经在一份现成代码里看到了 SetStyle(UserPaint),优先怀疑是同一份代码里的水印绘制问题。真要在 UserPaint 模式下工作,必须自己在 OnPaint 里补画边框和光标,维护成本会明显上升。

5.3 中文输入法打字时水印闪烁

中文输入法在打字时会触发 WM_IME_STARTCOMPOSITION 和 WM_IME_ENDCOMPOSITION,如果水印绘制逻辑只看 Focused 和 Text 长度,组合窗口出现时水印会闪几下,甚至把输入候选框顶到奇怪位置。

解决:在 WndProc 里拦截这两条消息,调用 Invalidate;同时把 ImeMode 设为 On,让输入法状态可控。WinForms 在这个点上很像黑匣子,修完记得在微软拼音和搜狗输入法下各测一轮。

private const int WM_IME_STARTCOMPOSITION = 0x010D; private const int WM_IME_ENDCOMPOSITION = 0x010E; protected override void WndProc(ref Message m) { if (m.Msg == WM_IME_STARTCOMPOSITION || m.Msg == WM_IME_ENDCOMPOSITION) { Invalidate(); } base.WndProc(ref m); }

Invalidate 本身开销很低,不会有性能问题,放心调用。

5.4 多行加滚动条后水印从第一行漂到中间

多行 TextBox 文本超过可视区域出现滚动条后,水印固定在 ClientRectangle 的某个位置,但如果你沿用了 VerticalCenter,它会停在视觉中线,看起来就是漂到了第二三行附近。

解决:多行时把 WatermarkTextFormat 改为 Left | Top,并在 WM_VSCROLL、WM_HSCROLL 后 Invalidate,让滚动后强制重绘一次。真机表现是滚动停下瞬间水印回到左上角,不会出现跟随内容滚动的错觉。

5.5 EM_SETCUEBANNER 在某些环境不显示

如果选了 API 路线,最隐蔽的坑是 Win7 或某些精简系统上,PasswordChar 文本框怎么发消息都不出现提示文字;RichTextBox 更是完全没有 cue banner。

解决:遇到密码框直接换自绘控件,不要在同一个控件里混用两个方案。API 路线可以作为快速原型,一旦出现环境差异,立刻切到第 3 章的代码,不要花时间查注册表或系统补丁,那是一条死路。

6. 进阶:从输入框水印到多行多列文字水印:窗口防截图方案怎么落地

6.1 透明置顶水印窗体的最小写法

如果你的真实需求是防截图,比如“内部资料 + 工号 + 时间”,那要的不是 Placeholder 而是覆盖在主界面上层的多行多列文字。常见做法是一个置顶透明窗体,设置 WS_EX_TRANSPARENT 让鼠标点击穿透。

public partial class WatermarkOverlay : Form { public WatermarkOverlay() { FormBorderStyle = FormBorderStyle.None; ShowInTaskbar = false; TopMost = true; BackColor = Color.Magenta; TransparencyKey = Color.Magenta; DoubleBuffered = true; this.ShowWithoutActivation = true; } protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT cp.ExStyle |= 0x00000080; // WS_EX_TOOLWINDOW return cp; } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); e.Graphics.TranslateTransform(20, 40); e.Graphics.RotateTransform(-30); Font font = new Font("微软雅黑", 12F); // 平铺多行多列文字水印 for (int y = 0; y < Height; y += 120) { for (int x = 0; x < Width; x += 320) { e.Graphics.DrawString( "内部资料 · " + Environment.UserName + " · " + DateTime.Now.ToString("MM-dd HH:mm"), font, Brushes.Gray, x, y); } } } }

要说明的边界:TransparencyKey 方案是 0/1 透明,水印文字颜色选纯灰,背景全部透明,做不到半透明灰度效果。想控制透明度就用 UpdateLayeredWindow,那是另一套代码。RotateTransform 前先 TranslateTransform 是为了让旋转中心偏移,否则以左上角为轴转,平铺位置会乱。

6.2 怎么验证窗口水印真的生效

验证不能只靠肉眼看屏幕。做法是用系统截图工具截全屏,然后把图片放大看水印文字是否进入截图;如果屏幕上能看到、截图里没有,说明它只是覆盖层,不符合防截图预期。实际项目中我一般把水印文字间距调到 120 像素一行、320 像素一列,字号 12 号,灰度 128。太密会干扰录入,太疏拍照时又读不出来。

我在这块也翻过车:把 Placeholder 当防截图水印交付,在客户现场被指出输入框没有提示文字。后来每次听到“加个水印”,都会先确认一句它是给谁看、什么时候消失。把这两类需求分开之后,WinForms 水印方案其实都很薄,难的是判断入口。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 21:07:07

版本控制信息泄露:Git / SVN / HG 泄露(CTFHub 题解)

版本控制信息泄露&#xff1a;Git / SVN / HG 泄露&#xff08;CTFHub 题解&#xff09; 目录 一、漏洞背景与原理二、通用探测思路三、Git 泄露 —— Stash四、Git 泄露 —— Index五、SVN 泄露六、HG&#xff08;Mercurial&#xff09;泄露七、修复与防御建议八、总结 一、…

作者头像 李华
网站建设 2026/9/28 21:06:28

MySQL数据库基础(3):库的操作

&#x1f338;雨落在了我的手上&#xff1a;个人主页 &#x1f41f;个人仓库&#xff1a;Gitee仓库 ❄️个人专栏&#xff1a;<<JaveSe>> <<C语言>> <<C语言数据结构>> <<Java数据结构 >> <<MySQL数据库基础 >>…

作者头像 李华
网站建设 2026/9/28 21:05:40

AI Agent知识获取管道:RAG检索增强生成从切片到检索的TypeScript实战

1. 为什么知识获取管道是 AI Agent 的分水岭很多人搭 AI Agent 的时候&#xff0c;第一反应是去调模型、写提示词、接工具&#xff0c;觉得只要模型够强、工具够多&#xff0c;Agent 就能干活。但真正跑过几个项目之后你会发现&#xff0c;决定一个 Agent 好不好用的&#xff0…

作者头像 李华
网站建设 2026/9/28 21:05:05

Redis大key删除把我坑惨了,分享这个血泪教训

凌晨三点&#xff0c;我盯着监控面板上持续飙高的Redis内存使用率&#xff0c;手心里全是汗——刚刚执行的DEL命令不仅没释放内存&#xff0c;反而让集群的QPS跌到了两位数。这是一次典型的「大key删除」事故&#xff0c;而背后的教训值得每个用过Redis的人警惕。 场景还原&…

作者头像 李华
网站建设 2026/9/28 21:04:38

AgentScope多智能体协作实战:消息传递、记忆机制与工程调优

多智能体系统这两年从论文里的概念一路卷到了工程落地&#xff0c;但真正让我愿意花时间写一篇长文来聊的框架并不多。AgentScope 算一个。第一次接触它是在一个需要把多个角色智能体编排起来完成复杂任务的项目里&#xff0c;当时试过几种方案&#xff0c;要么抽象太重、要么调…

作者头像 李华