C#重写DateTimePicker的OnPaint无效果,还需进行其他操作吗?
问题根因
DateTimePicker属于Windows Forms封装的系统原生通用控件,默认由操作系统直接负责绘制流程,不会触发标准Paint事件,因此重写OnPaint方法默认不会生效,事件列表中不存在Paint事件也是该特性导致的,不是编写的绘制代码逻辑错误。
解决方案
需要手动开启控件的用户绘制模式,同时捕获系统绘制消息自行处理绘制逻辑,具体实现如下:
完整实现代码
public class BorderlessDateTimePicker : DateTimePicker { public BorderlessDateTimePicker() { this.Font = new System.Drawing.Font("Microsoft Sans Serif", 36F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Format = DateTimePickerFormat.Time; this.ShowUpDown = true; this.Size = new Size(300, 75); // 开启用户绘制模式,允许自定义绘制逻辑生效 SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true); } protected override void WndProc(ref Message m) { const int WM_PAINT = 0x000F; // 捕获系统绘制消息,自行处理绘制 if (m.Msg == WM_PAINT) { using (Graphics g = Graphics.FromHwnd(this.Handle)) { OnPaint(new PaintEventArgs(g, ClientRectangle)); } m.Result = IntPtr.Zero; return; } base.WndProc(ref m); } protected override void OnPaint(PaintEventArgs e) { // 绘制控件背景 e.Graphics.Clear(BackColor); // 绘制时间文本,格式可根据需求调整 string timeText = Value.ToString("HH:mm"); using (Brush textBrush = new SolidBrush(ForeColor)) { e.Graphics.DrawString(timeText, Font, textBrush, 2, 2); } // 用父容器背景色绘制边框,覆盖原生控件边框,实现无边框效果 using (Pen borderPen = new Pen(Parent.BackColor, 2)) { e.Graphics.DrawRectangle(borderPen, 0, 0, Width - 1, Height - 1); } } }
补充说明
- 如果需要保留原生上下调整按钮的功能,可在绘制时预留右侧按钮区域,也可自行绘制自定义样式的调整按钮,通过处理鼠标点击事件实现调整逻辑
- 如需适配控件启用/禁用状态,可在OnPaint中增加
Enabled属性判断,对应调整文本、背景的显示样式 - 若不需要时间调整功能,将
ShowUpDown设为false后,绘制逻辑可进一步简化
内容的提问来源于stack exchange,提问作者Student228
相关产品推荐
相关产品推荐

