WinForm应用实战开发指南 - 如何用自定义控件丰富界面效果处理?
Winform界面开发部分往往也用到了自定义的用户控件对应一些特殊的界面或者常用到的一些局部界面内容我们可以使用自定义的用户控件来提高界面的统一性同时也增强了使用的便利性。如我们Winform界面中用到的分页控件、附件显示内容、以及一些公司、部门、菜单的下拉框列表等等由于重复多处使用因此一处封装多处收益。PS给大家推荐一个C#开发可以用到的界面组件——DevExpress WinForms它能完美构建流畅、美观且易于使用的应用程序无论是Office风格的界面还是分析处理大批量的业务数据它都能轻松胜任DevExpress新旧版本帮助文档获取可点击这篇文章查看——《界面控件DevExpress v26.1帮助文档大全CHM版本》回顾Winform界面中自定义的用户控件处理场景之前介绍了不少的控件使用、以及自定义控件的使用例子如模仿牙医管家的软件界面的部分来创建一些自定义部分的内容。根据其中显示的内容部分制作了一个用户控件在其中添加一个LayoutControl方便控制布局添加一些标签以及设置了一些图标得到下图所示。其中定义的用户控件的源码部分继承自XtraUserControl用户控件基类如果是传统样式的Winform界面可以继承自UserControl修改其中源码增加对应的属性方便动态设置用户控件的相关属性如颜色块、项目背景色以及绑定的对象信息等内容。然后通过自定义控件的事件或者方法对界面内容进行更新处理即可完成后我们看界面的效果如下所示较为符合实际的效果即可。一般来说一个窗体用户控件不多的情况下Winform界面的效果还是挺好的如果界面的用户控件很多如超过几千个那么可能会有性能问题。动态展现大量历史号码信息的自定义控件的时候就会出现一些句柄创建错误的问题。控件集合可以通过布局TableLayoutPanel表格布局或者FlowLayoutPanel顺序流布局来添加即可如果利用TableLayoutPanel来展示那么需要设置好每列的宽度或者比例如下界面所示。表格的行列定义如下所示。由于自定义控件我们需要跟踪用户的单击处理并且需要把这个逻辑逐步推动到顶级界面上去进行处理因此需要定义一个事件信息如下所示。/// summary /// 事件处理 /// /summary public EventHandlerClickEventData ClickEventHandler { get; set; }控件的动态添加处理可以同时指定它的匿名事件的处理逻辑从而对控件的事件进行更新。var controlList new ListLotteryItemControl2(); foreach (var info in list) { var control new LotteryItemControl2(); control.Qi info.LineNo.ToString(D2); var numberList new Liststring() { info.No1.ToString(D2), info.No2.ToString(D2), info.No3.ToString(D2), info.No4.ToString(D2), info.No5.ToString(D2), info.No6.ToString(D2), info.No7.ToString(D2), }; control.NumberList numberList; control.BindData(); control.ClickEventHandler (s, data) { //遍历所有的控件统一处理样式 foreach (var subCtrl in panel.Controls) { if (subCtrl is LotteryItemControl2 lottery) { lottery.SetSelected(data); } } }; controlList.Add(control); } this.panel.Controls.AddRange(controlList.ToArray());如果我们不喜欢每个控件都对事件进行一个层层的处理也可以引入MediatR来实现事件总线的处理。我们在程序启动的时候注入对应的接口服务IMediator那么就可以通过该静态类的 GetService方法获取对应的注入接口IMediator我们需要利用该接口来发送Send请求/应答命令或者发布Publish消息的处理。public partial class TestMediatR : BaseForm { private readonly IMediator _mediator; public TestMediatR() { InitializeComponent(); _mediator ServiceLocator.GetServiceIMediator(); }MediatR是一个跨平台通过一种进程内消息传递机制进行请求/响应、命令、查询、通知和事件的消息传递并通过C#泛型来支持消息的智能调度其目的是消息发送和消息处理的解耦。它支持以单播和多播形式使用同步或异步的模式来发布消息创建和侦听事件。它主要的几个对象IMediator主要提供Send与Publish方法需要执行的命令都是通过这两个方法实现IRequest、IRequest命令查询 | 处理类所继承的接口一个有返回类型一个无返回类型一个查询对应一个处理类程序集只认第一个扫描到的类。IRequestHandler实现Handle方法 命令处理接口。命令查询 | 处理类继承它也可以继承AsyncRequestHandler实现抽象Handle方法、RequestHandler实现抽象Handle方法接口INotification命令查询 | 处理类所继承的接口这个没有返回与IRequest不通的是可以对于多个处理类INotificationHandler与IRequestHandler一样的只不过这是INotification的处理接口例如我们发送消息后收到应答消息结果展示在界面中的如下所示。/// summary /// 使用请求、应答的消息进行测试获得返回结果后输出显示 /// /summary private async void btnSend_Click(object sender, EventArgs e) { //应答处理 var outputMessage await _mediator.Send(new RetrieveInfoCommandRequest { Text this.txtSend.Text }); Console.WriteLine(outputMessage.OutputMessage); this.txtReceived.AppendText(outputMessage.OutputMessage Environment.NewLine); }如果控件比较多处理的时候刷新的时候记得移除面板上已经添加的控件。//清空界面 while (panel.Controls.Count 0) { var controltoremove panel.Controls[0]; panel.Controls.RemoveAt(0); controltoremove.Dispose(); } panel.Controls.Clear();Winform界面中自定义的用户控件处理例如在附件管理的时候对于一些窗体的信息我们需要了解该业务对应的附件信息有几个并且提供入口可以查看或者管理附件列表那么可以根据需要封装一个自定义附件管理的自定义用户控件。在实际界面应用的时候由于附件管理的自定义控件已经封装好了所以在使用的时候拖动到界面即可如下界面所示。我们在做病历管理的时候就需要大量用到不同的分类的附件信息的展示如下界面效果所示。还有就是有时候对于权限管理里面部门信息在不少的地方用到如果每次对原始的下拉列表处理那么增加不少工作量如果把它封装为自定义控件和常规的控件一样使用即可就会很方便如下界面所示。它的实际展示效果如下所示。单击下拉列表后展示部门的列表信息。同理用户控件一旦创建后我们可以在很多需要的地方直接使用省却初始化的一些代码操作。我们在初始化的时候显示相关的部门列表选择后获得部门的ID也可以设置部门的ID。/// summary /// 部门显示控件 /// /summary public partial class DeptControl : XtraUserControl { public string ParentOuID -1; /// summary /// 选择的值发生变化的时候 /// /summary public event EventHandler EditValueChanged; public DeptControl() { InitializeComponent(); this.txtDept.EditValueChanged new EventHandler(cmbUpperOU_EditValueChanged); } void cmbUpperOU_EditValueChanged(object sender, EventArgs e) { if (EditValueChanged ! null) { EditValueChanged(sender, e); } } private async void DeptControl_Load(object sender, EventArgs e) { if (!this.DesignMode) { //限定用户的选择级别 var list await Portal.gc.GetMyTopGroup(); foreach (OuInfo OuInfo in list) { if (OuInfo ! null) { this.ParentOuID OuInfo.Id.ToString(); } } Init(); } }需要可以响应相关的编辑事件用来触发关联的信息变化如下所示是自定义控件的使用代码。public partial class FrmEditUser : BaseEditForm { public FrmEditUser() { InitializeComponent(); this.txtDept.EditValueChanged new EventHandler(txtDept_EditValueChanged); } void txtDept_EditValueChanged(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txtDept.Value)) { InitManagers(txtDept.Value.ToInt32()); } }在介绍一个场景我们在一些选择用户的界面中如CRM中对于分配用户、工作流中选择流程用户的操作中往往需要选择系统的人员列表可以多个选择那么我们可以设计界面如下所示。其中选择的人员用红色方框标识这个部分的用户和移除图标是自定义控件界面如下所示。主要就是方便对用户进行显示和移除设置的一些简单的封装。在比如在工作流的创建入口中我们展示相关可以创建流程的快速入口通过一些图片、文字来展示工作流程的信息单击事件进行弹出不同的流程对话框处理过程。这个过程主要就是美观性的要求是相对于全部文本信息的单调有一些改善的效果。本文转载自博客园 - 伍华聪

相关新闻

界面组件DevExpress WinForms v23.2 - 数据可视化功能升级

界面组件DevExpress WinForms v23.2 - 数据可视化功能升级

DevExpress WinForms拥有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜…

2026/10/18 5:54:20 阅读更多 →
TI C6000 DSP SYSCFG模块详解:从寄存器配置到系统级调试实战

TI C6000 DSP SYSCFG模块详解:从寄存器配置到系统级调试实战

1. 项目概述:为什么你需要关注SYSCFG模块?如果你正在基于TI C6000系列DSP(比如C674x)做嵌入式开发,尤其是涉及实时信号处理、多核通信或者复杂外设管理,那么你迟早会跟一个叫SYSCFG(System Conf…

2026/10/17 16:51:00 阅读更多 →
界面开发框架DevExpress XAF v24.1新版预告 - 跨平台应用UI(二)

界面开发框架DevExpress XAF v24.1新版预告 - 跨平台应用UI(二)

DevExpress XAF是一款强大的现代应用程序框架,允许同时开发ASP.NET和WinForms。XAF采用模块化设计,开发人员可以选择内建模块,也可以自行创建,从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。本文中的内容概述了XA…

2026/10/20 4:13:14 阅读更多 →

最新新闻

用原理图设计FPGA电子琴:分频表驱动蜂鸣器音乐

用原理图设计FPGA电子琴:分频表驱动蜂鸣器音乐

简介:通过Quartus原理图设计方法实现的电子琴FPGA工程包,面向数字电路、EDA与FPGA入门学习者,演示从音符频率生成、定时计数、数模转换到乐曲存储与播放的完整音乐合成系统。资源共413个文件,压缩包5.42MB,主要包含原理…

2026/10/20 13:14:06 阅读更多 →
多镜头视频生成一致性难题如何解?FilmWeaver框架与实操要点

多镜头视频生成一致性难题如何解?FilmWeaver框架与实操要点

做多镜头视频生成的人应该都有这种感觉:单镜头生成已经很顺手之后,最头疼的反而不是画质,而是“一致性”。你先生成一个人走进咖啡店的镜头,再换一个机位生成同一个人坐在窗边,十次有九次会得到两个长得完全不像的人。…

2026/10/20 13:14:06 阅读更多 →
FlashVSR-v1.1-bf16开发者进阶:从convert_weights.py权重转换到Metal稀疏注意力内核的二次开发路线

FlashVSR-v1.1-bf16开发者进阶:从convert_weights.py权重转换到Metal稀疏注意力内核的二次开发路线

【免费下载链接】FlashVSR-v1.1-bf16 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/FlashVSR-v1.1-bf16 点击查看 免费下载 FlashVSR-v1.1-bf16 是面向 Apple Silicon 的 FlashVSR v1.1 视频超分权重仓库:它把一步式、流式扩散 4 视频超…

2026/10/20 13:14:06 阅读更多 →
RAG生产级优化实战:从索引分块到评估迭代的完整链路

RAG生产级优化实战:从索引分块到评估迭代的完整链路

做了两年RAG相关的项目,说实话,最初能跑通demo的那点兴奋,很快就被线上badcase打没了。用户一句口语化的问题,检索模块经常召不回关键段落,大模型又一本正经地答非所问。后来我花了大把时间在检索链路和索引侧修补&…

2026/10/20 13:14:06 阅读更多 →
Git批量创建本地分支:克隆所有远程分支的实战指南

Git批量创建本地分支:克隆所有远程分支的实战指南

1. 为什么“git clone 所有分支”是个伪命题先把一个容易踩坑的认知掰正:git clone默认行为其实已经把所有分支的提交对象都拉到了本地。你打开.git目录,里面objects文件夹装的就是完整的提交历史,远端每一个分支指向的 commit 都在里面躺着。…

2026/10/20 13:14:06 阅读更多 →
电力-热力-算力三维协同:DQN强化学习实现数据中心节能优化

电力-热力-算力三维协同:DQN强化学习实现数据中心节能优化

数据中心这行当,这几年最卷的已经不是单纯的算力堆砌,而是“电费账单”和“散热瓶颈”的双重夹击。我陆续做过几个和智能调度相关的项目,其中“电力-热力-算力三维协同”这套思路,配合DQN(Deep Q-Network)深…

2026/10/20 13:13:05 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →