c# 如何自定义一个 control
技术百科
畫卷琴夢
发布时间:2026-01-27
浏览: 次 继承 Control 类是 WinForms 自定义控件最直接方式,需禁用默认背景擦除、启用双缓冲与焦点支持,并提供无参构造函数及设计器特性以确保可用性。
继承 Control 类是最直接的方式
自定义控件本质是扩展 System.Windows.Forms.Control(WinForms)或 System.Windows.Controls.Control(WPF),前者更轻量、适合底层绘制与事件控制。不建议从 UserControl 开始——它自带容器逻辑和设计器依赖,反而限制对绘制、消息循环、焦点行为的精细控制。
- 若需完全掌控绘制(比如画波形图、仪表盘),继承
Control并重写OnPaint - 若要支持双缓冲防闪烁,设
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true) - 必须手动调用
base.OnCreateControl()和base.OnHandleCreated(),否则生命周期钩子可能失效 - 别忘了在构造函数里设
ResizeRedraw = true,否则窗口缩放时不会自动重绘
重写 OnPaint 时绕开 GDI+ 默认背景擦除
默认 Control 在每次 OnPaint 前会用 BackColor 填充整个客户区,这会导致自绘内容被覆盖或出现残影。尤其在动画或高频刷新场景下特别明显。
- 在构造函数中关闭默认擦除:
this.SetStyle(ControlStyles.Opaque, true)
- 同时禁用背景绘制:
this.SetStyle(ControlStyles.ResizeRedraw, true) - 重写
OnPaintBackground为空实现,避免父类填充背景 -
OnPaint中只用传入的Graphics绘制内容,不要调用e.Graphics.Clear(...)
protected override void OnPaint(PaintEventArgs e) {
// 不调用 base.OnPaint(e)
using (var pen = new Pen(Color.Blue, 2)) {
e.Graphics.DrawLine(pen, 10, 10, 100, 100);
}
}
响应鼠标/键盘事件必须显式启用焦点支持
直接继承 Control 的控件默认不可聚焦,KeyDown、KeyPress 等事件根本不会触发,哪怕你重写了 OnKeyDown。
- 构造函数中调用
this.TabStop = true和this.TabIndex = 0 - 重写
CanSelect属性返回true - 在
OnMouseDown中主动调用this.Focus(),否则点击不会获得输入焦点 - 若需捕获非客户端区域(如边框)的鼠标,需处理
WM_NCHITTEST消息,通过WndProc拦截
设计器支持需要 [ToolboxItem] 和默认构造函数
没有无参构造函数或缺少特性标记,控件拖不到 WinForms 设计器里,且属性面板不显示自定义属性。
- 必须提供 public 无参构造函数:
public MyCustomControl() { InitializeComponent(); } - 添加
[ToolboxItem(true)]特性,否则设计器忽略该类型 - 让属性可序列化:对希望在设计器中编辑的属性加
[Browsable(true)]、[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] - 若属性影响外观(如
LineColor),重写OnPropertyChanged并调用Invalidate()触发重绘
MouseLeave,或键盘焦点在嵌套控件间跳转时丢失。这些往往要靠精确拦截 WndProc 和检查 NativeWindow.AssignHandle 状态来定位。
# ai
# 会用
# 写了
# windows
# 重写
# 自带
# 若需
# 自定义
# 跳转
# 可用性
# 鼠标
# public
# win
# 循环
# c#
# 构造函数
# 键盘事件
# 事件
# red
# this
# 继承
# wpf
# 父类
# 重绘
# 擦除
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Python网络日志追踪_请求定位解析【教程】
- Windows执行文件被SmartScreen拦截
- Windows笔记本无法进入睡眠模式怎么办?(电源
- php中::能访问全局变量吗_全局作用域与类作用域
- 如何在Golang中处理URL参数_Golang
- Windows10电脑怎么设置防火墙出站规则_Wi
- Linux怎么禁止Root用户远程登录_Linux
- VSC怎么在PHP中调试MySQL_数据库交互排查
- php485在macos下怎么配置_php485
- 如何使用Golang实现RPC序列化与反序列化_G
- Windows系统时间服务错误_W32Time服务
- Windows10怎么备份注册表_Windows1
- Win11怎么关闭触摸键盘图标_Windows11
- Windows10如何更改日期格式_Win10区域
- c++如何利用doxygen生成开发文档_c++
- Win11怎么设置默认图片查看器_Windows1
- Mac如何修改Hosts文件?(本地开发与屏蔽网站
- 如何解决Windows时间不准的问题?(自动同步设
- Python高性能计算项目教程_NumPyCyth
- Mac上的iMovie如何剪辑视频?(新手入门教程
- Win11怎么关闭通知消息_屏蔽Windows 1
- Windows10如何更改任务栏高度_Win10解
- c++怎么设置线程优先级与cpu亲和性_c++ 多
- MAC怎么用连续互通相机里的“桌上视角”_MAC在
- Win11怎么查看电脑配置_Win11硬件配置详细
- 如何使用正则表达式提取以编号开头、后接多个注解的逻
- Windows10如何彻底关闭自动更新_Win10
- Win11怎么打开旧版计算器_Win11恢复传统计
- 如何在Golang中编写异步函数测试_Golang
- Mac的访达(Finder)怎么用_Mac文件管理
- php后缀怎么变mp4能播放_让php伪装mp4正
- mac怎么退出id_MAC退出iCloud账号与A
- Win11怎么设置默认邮件客户端 Win11修改M
- 本地php环境出现502错误_nginx或apac
- Win10系统怎么查看端口状态_Windows10
- 如何在Golang中处理云原生事件_使用Event
- Win11怎么更改计算机名_Windows11系统
- mac怎么分屏_MAC双屏显示与分屏操作技巧【指南
- php怎么下载安装并配置环境变量_命令行调用PHP
- Win11怎么查看已连接wifi密码 Win11查
- 用Python构建微服务架构实践_FastAPI与
- php嵌入式需要什么环境_搭建php+linux嵌
- Linux怎么修改用户密码_Linux系统pass
- Python安全爬虫设计_IP代理池与验证码识别策
- Win11怎么关闭用户账户控制UAC_Window
- Win10怎么卸载金山毒霸_Win10彻底卸载金山
- 为什么Go需要go mod文件_Go go mod
- Windows10系统怎么查看防火墙状态_Win1
- 如何在Golang中处理模块冲突_解决依赖版本不兼
- 如何开启Windows的远程服务器管理工具(RSA


QQ客服