C# Panel控件设置属性后滚动不生效,使用Paint绘制收据时如何启用滚动?
问题原因
WinForm 中 Panel 控件的默认 AutoScroll 滚动机制仅针对其内部的子控件生效,你通过 Paint 事件使用 GDI 直接绘制的文本内容不属于 Panel 的子控件,Panel 无法自动感知自定义绘制内容的实际尺寸,因此不会触发滚动条显示。
解决方案
- 第一步:先配置 Panel 基础属性
将 Panel 控件的AutoScroll属性设置为true,开启滚动支持。 - 第二步:适配绘制逻辑适配滚动偏移
在 Paint 事件开头添加坐标系偏移代码,避免滚动后绘制内容错位。 - 第三步:主动设置滚动区域尺寸
绘制完成后根据你的收据总高度,手动设置AutoScrollMinSize属性告知 Panel 内容总尺寸,触发滚动条显示。
修改后的完整代码
private void panel1_Paint(object sender, PaintEventArgs e) { System.Drawing.Graphics g = e.Graphics; // 新增:适配滚动偏移,滚动后内容不会错位 g.TranslateTransform(panel1.AutoScrollPosition.X, panel1.AutoScrollPosition.Y); Font font = new Font("Courier New", 8); float fontHeight = font.GetHeight(); int upperY = 20; g.DrawString("NCR Gravel and Sand Enteprise", new Font("Courier New", 10), new SolidBrush(Color.Black), 80, upperY); upperY = upperY + 15; g.DrawString("42 Felix Ave. Brgy San Isidro Cainta Rizal", font, new SolidBrush(Color.Black), 60, upperY); upperY = upperY + 15; g.DrawString("Cecil R. delas Armas Prop.", font, new SolidBrush(Color.Black), 110, upperY); upperY = upperY + 15; g.DrawString("Tel Nos: 647-8021/ 296-466/ 492-1773/ 341-7840", font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Cell #: 0922-853-7840", font, new SolidBrush(Color.Black), 130, upperY); upperY = upperY + 15; g.DrawString("==============================================", font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; string info = "Reference Number:" + Salesrecord_module.refnumber.PadRight(13); g.DrawString(info, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Date: " + Salesrecord_module.date, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Customer Name:" + Salesrecord_module.customer, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Customer Address:" + Salesrecord_module.address, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Cashier:" + Salesrecord_module.assist, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("==============================================", font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; string top = "x".PadRight(5) + "".PadRight(5) + "Item Name".PadRight(30) + "Price"; g.DrawString(top, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("----------------------------------------------", font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; for (int i = 0; i < Salesrecord_module.cartcount; i++) { string item = Salesrecord_module.quantitylist[i].PadRight(5) + Salesrecord_module.Unitlist[i].PadRight(5) + Salesrecord_module.productnamelist[i].PadRight(30) + Salesrecord_module.Pricelist[i]; g.DrawString(item, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 20; } g.DrawString("----------------------------------------------", font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("SubTotal:".PadRight(40) + Salesrecord_module.sub, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Fee:".PadRight(40) + Salesrecord_module.fee, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Total:".PadRight(40) + Salesrecord_module.total, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("----------------------------------------------", font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Payment:".PadRight(40) + Salesrecord_module.amount, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Change:".PadRight(40) + Salesrecord_module.change, font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("==============================================", font, new SolidBrush(Color.Black), 40, upperY); upperY = upperY + 15; g.DrawString("Thank you for purchasing", font, new SolidBrush(Color.Black), 120, upperY); // 新增:手动设置内容总尺寸,触发滚动条显示,宽度可根据实际收据宽度调整 panel1.AutoScrollMinSize = new Size(400, upperY + 20); // 释放GDI资源,避免内存泄漏 font.Dispose(); }
附加优化建议
- 不要在 Paint 事件中重复创建 Font、SolidBrush 等 GDI 对象,这类对象占用非托管资源,建议提到全局复用,或者使用
using包裹声明,用完自动释放。 - 如果收据内容会动态变更(比如商品数量增减),变更后调用
panel1.Invalidate()触发重绘,自动更新滚动区域尺寸。

内容的提问来源于stack exchange,提问作者Nathaniel Peñaranda
相关产品推荐
相关产品推荐

