调出隐藏事件OnPaint的方法

本文探讨了VB.NET环境中控件事件调用及数据绑定的问题,包括如何实现自定义控件的OnPaint事件、如何处理不同列数的DataGrid之间的数据传递,并讨论了隐藏特定列的方法。

我这边有个控件,事件窗口里没有OnPaint这个事件,我有想到建个自定义控件,把这个OnPaint事件调出来可以用,但是不知道怎么弄

那怎么样才能调用这个方法,事件窗口没这个选项

首先你要窗体或者控件无效接着就进行重绘操作了
有没有直接点的,一般其它控件,在那个事件窗口里,双击那个Paint事件,程序里就有
这样形式的代码,我就把画图代码写在里面

第1个页面里有个11列的DATAGRID,事先的列名都是公司里规定好的,不许我们改动的,我给它捆绑了个11列的DATATABLE作为数据源

第2个页面里有个9列的DATAGRID,事先的列名也都是公司里规定好的,同样不许我们改动,它和第一个页面里的DATAGRID中的9列完全相同,只是少了2列.我用以上的Session变量把名为dt2的DATATABLE(共有11列)传递给第2个页面
把来自第1个页面的名为dt2的DATATABLE(共有11列)从Session变量中取出来;
然后大麻烦来了,我在第2个页面中不知如何把dt2的多余两列隐藏掉,其余9列准确无误地捆绑在预先设定好的9列的DATAGRID中,在页面上显示出来.
我是新手,公司又规定只能用VB.NET在VS2003环境下做,公司的环境又缺乏交流,觉得很难,最近的任务还剩一小块,已经拖了数月了,郁闷哪.

可以再声明个DataTable.把你要的数据传过去...

这个开发方式好麻烦。。控件拖好了。但你们却只能做其他的东西。不能动。。。
LZ你也可以把DataTable 中多的哪两列用dt.Column.Remove(string ColumnName)移除就行啊
那么隐藏了2列之后如何把剩下的9列与那个预先设定好的DATAGRID绑定啊?
由于隐藏的两列分别是第一列和最后一列,隐藏以后序号不是麻烦了吗?
先把你的数据和id绑定指定的datagrid上,然后影藏datagrid要影藏的列,显示出来以后就是你想看到的9列啦.
问题是我们公司的代码,页面都是预先做好的,不许我们改动
第1个页面中的DATAGRID,有11列
第2个页面中的DATAGRID,只有9列
数据源是11列的,你在第二个datagrid只显示9个列,只添加9个要显示的列,其他的两个列不帮定 不就可以了吗?
我们刚毕业的大学生又没做过类似的项目,单位里又不组织培训,又没有团队合作,一个个都各自做自己的
C#如何生成swf文件的缩略图?最好有代码参考,
这些都是要调用ffmpeg的,如果不调用这个直接用C#代码不知道怎么做。
就是说我在前台有个DropDownList,开始的状态如下:
在后台响应另外一个控件后,从后台程序让这个DropDownList展开,也就是成为如下形式
或者说后台focus()到那里后,按下回车让它展开?
模拟的话你可以搜google,里面很多,怎么都不会使用搜索引擎来解决问题呢?
我是一名初学者,现请教高手下,c#windows编程如何使用和连接数据库(以sql server2008为例),最好能给一个完整的例子
找个demo,慢慢看吧, msdn中应该能找到例程。
Global.asax文件中添加了以上代码,在VS2010调试时运行正常,部署到服务器(2008R2)上时,使用.NET4经典模式添加通配符脚本映射后运行正常,可一修改为“集成”模式后,就不管用了,访问如http://wapit.cn/xxxx时,显示404错误:找不到资源……
网上查了N多资料,都说集成模式不用配置直接就可用的,可就是不对,请问:我哪步不到位?谢谢指点。
来源: nba直播

<think>我们正在讨论如何重写UserControl的OnPaint方法来实现自定义绘制。根据引用[3]中的提示,有些控件(如TextBox)默认不支持UserPaint,需要设置ControlStyles.UserPaint标志。但UserControl本身是支持自定义绘制的,不过我们仍然需要注意一些细节。 步骤: 1. 创建一个继承自UserControl的自定义控件类。 2. 在构造函数中设置双缓冲(可选,用于减少闪烁)和设置UserPaint样式(如果需要)。 3. 重写OnPaint方法,使用Graphics对象进行绘制。 4. 确保在绘制时考虑控件的整个客户区。 注意:UserControl默认已经支持绘制,所以不需要特别设置UserPaint样式。但是,如果遇到绘制问题,可以尝试设置。 根据引用[1]和[2],我们了解到自定义绘制通常通过重写OnPaint方法,并在其中使用Graphics对象进行绘制。 下面是一个简单的示例,演示如何重写UserControl的OnPaint方法,绘制一个自定义的边框和背景。 代码示例: ```csharp using System; using System.Drawing; using System.Windows.Forms; public class CustomPaintUserControl : UserControl { // 可选:自定义属性,用于设置背景色 private Color _backgroundColor = Color.LightBlue; public Color BackgroundColor { get { return _backgroundColor; } set { _backgroundColor = value; this.Invalidate(); // 触发重绘 } } public CustomPaintUserControl() { // 设置双缓冲以减少闪烁 this.DoubleBuffered = true; // 设置控件样式:如果需要用户绘制,可以设置UserPaint,但UserControl默认已经包含该样式 // this.SetStyle(ControlStyles.UserPaint, true); // 注意:UserControl默认已经支持UserPaint,所以通常不需要再设置 } protected override void OnPaint(PaintEventArgs e) { // 调用基类的OnPaint以确保控件上的子控件被正确绘制 base.OnPaint(e); // 获取Graphics对象 Graphics g = e.Graphics; // 绘制背景(使用自定义背景色) using (SolidBrush brush = new SolidBrush(BackgroundColor)) { g.FillRectangle(brush, this.ClientRectangle); } // 绘制一个红色边框 using (Pen pen = new Pen(Color.Red, 3)) { // 注意:绘制边框时,要考虑到Pen的宽度,避免被裁剪 Rectangle borderRect = new Rectangle(0, 0, this.Width - 1, this.Height - 1); g.DrawRectangle(pen, borderRect); } // 绘制一些文本 using (Font font = new Font("Arial", 12)) { g.DrawString("Hello, Custom Paint!", font, Brushes.Black, new PointF(10, 10)); } } } ``` 关键点说明: 1. 在构造函数中设置`DoubleBuffered = true`可以减少绘制时的闪烁。 2. 重写`OnPaint`方法时,通常需要调用`base.OnPaint(e)`,以确保控件上的子控件(如果有)被正确绘制。 3. 使用`using`语句来确保画笔、画刷等资源被及时释放。 4. 绘制边框时,注意矩形的位置和大小。因为Pen的宽度,如果从(0,0)开始绘制,宽度为Width,那么右边和下边可能会被裁剪掉一部分。所以这里我们绘制了一个从(0,0)开始,宽高为Width-1和Height-1的矩形。 注意:如果控件上有其他子控件,那么我们在绘制背景和边框时,要注意不要覆盖子控件(因为子控件会绘制在背景之上,而边框在背景之上)。这里我们调用了base.OnPaint(e),它会在我们绘制之后绘制子控件?实际上,基类的OnPaint会先绘制背景(默认的背景绘制),然后绘制子控件。但我们在重写的OnPaint中先调用了base.OnPaint,然后再绘制边框和文字,这样我们的绘制内容可能会被子控件覆盖。所以,通常的做法是: - 先绘制自定义背景(覆盖整个控件) - 然后调用base.OnPaint(绘制子控件) - 最后绘制边框(在子控件之上)或者文本等。 但是,如果我们的边框不想被子控件覆盖,那么我们可以先调用base.OnPaint(让子控件先绘制),然后绘制边框(在子控件之上)。但这样边框可能会覆盖子控件。所以需要根据需求调整。 另一种做法:不调用base.OnPaint,而是自己绘制所有内容,包括背景。但是这样就不会绘制子控件了。所以对于有子控件的UserControl,必须调用base.OnPaint。 因此,我们通常这样安排: 1. 绘制背景(如果需要自定义背景) 2. 调用base.OnPaint(e) (这会绘制子控件) 3. 绘制前景(如边框、自定义文本等,这些会出现在子控件之上) 但是,如果我们的背景是纯色的,也可以通过设置BackColor属性,然后让基类去绘制背景(在base.OnPaint中会使用BackColor绘制背景)。所以,我们可以不绘制背景,而是设置BackColor属性,然后调用base.OnPaint。 修改后的OnPaint方法(只绘制边框和文本,背景由基类绘制): ```csharp protected override void OnPaint(PaintEventArgs e) { // 设置背景色,然后基类会绘制背景 this.BackColor = BackgroundColor; // 如果我们需要使用自定义背景色,可以在这里设置 // 调用基类的OnPaint,它会绘制背景和子控件 base.OnPaint(e); // 然后绘制边框(在子控件之上) using (Pen pen = new Pen(Color.Red, 3)) { Rectangle borderRect = new Rectangle(0, 0, this.Width - 1, this.Height - 1); e.Graphics.DrawRectangle(pen, borderRect); } // 绘制文本(也在子控件之上) using (Font font = new Font("Arial", 12)) { e.Graphics.DrawString("Hello, Custom Paint!", font, Brushes.Black, new PointF(10, 10)); } } ``` 注意:这样设置后,边框和文本会绘制在子控件的上方。如果不想覆盖子控件,可以调整绘制的位置和区域。 另外,如果控件大小改变需要重绘,可以监听Resize事件并调用Invalidate,或者设置ResizeRedraw样式: ```csharp public CustomPaintUserControl() { // ... this.SetStyle(ControlStyles.ResizeRedraw, true); } ``` 这样,当控件大小改变时,会自动重绘。 总结: 重写UserControl的OnPaint方法时,需要注意: 1. 是否调用base.OnPaint(通常需要调用,以绘制子控件) 2. 绘制顺序:先背景,再子控件,最后绘制边框等前景 3. 使用双缓冲和ResizeRedraw样式来优化绘制效果 如果遇到绘制问题,可以尝试设置ControlStyles.UserPaint和ControlStyles.OptimizedDoubleBuffer等样式。 根据引用[3],设置样式的方法: ```csharp this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 忽略WM_ERASEBKGND消息,减少闪烁 this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // 双缓冲 ``` 在UserControl中,我们可以在构造函数中设置这些样式。 §§相关问题§§ 1. 如何解决自定义绘制时控件闪烁的问题? 2. 在自定义绘制中,如何正确处理子控件的绘制顺序? 3. 如何实现UserControl的背景渐变效果?</think>### C# 重写 UserControl OnPaint 方法实现自定义绘制 在 C# 中重写 UserControl 的 OnPaint 方法可以实现完全自定义的控件绘制效果。以下是详细实现步骤和关键注意事项: #### 核心实现步骤 1. **创建自定义 UserControl 类** ```csharp public class CustomPaintUserControl : UserControl { // 自定义属性示例 private Color _borderColor = Color.Red; public Color BorderColor { get => _borderColor; set { _borderColor = value; Invalidate(); // 触发重绘 } } public CustomPaintUserControl() { // 关键设置:启用用户绘制模式 SetStyle(ControlStyles.UserPaint, true); // 启用双缓冲减少闪烁 SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // 控件大小变化时自动重绘 SetStyle(ControlStyles.ResizeRedraw, true); } } ``` [^3] 2. **重写 OnPaint 方法** ```csharp protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // 调用基类方法确保基础绘制 Graphics g = e.Graphics; // 1. 绘制背景 using (SolidBrush bgBrush = new SolidBrush(BackColor)) { g.FillRectangle(bgBrush, ClientRectangle); } // 2. 绘制自定义边框 using (Pen borderPen = new Pen(BorderColor, 3)) { Rectangle borderRect = new Rectangle(0, 0, Width - 1, Height - 1); g.DrawRectangle(borderPen, borderRect); } // 3. 绘制自定义文本 using (Font textFont = new Font("Arial", 12)) { g.DrawString("Custom Control", textFont, Brushes.Black, 10, 10); } } ``` [^1][^2] 3. **触发重绘机制** - 修改属性时调用 `Invalidate()` 方法 - 响应尺寸变化: ```csharp protected override void OnResize(EventArgs e) { base.OnResize(e); Invalidate(); // 尺寸变化时重绘 } ``` #### 关键注意事项 1. **必须设置绘制样式** ```csharp SetStyle(ControlStyles.UserPaint, true); // 启用用户绘制 SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // 双缓冲减少闪烁 ``` 这是实现自定义绘制的前提条件[^3]。 2. **绘制区域处理** - 使用 `ClientRectangle` 而非 `DisplayRectangle` - 坐标系统从 (0,0) 开始 - 边界处理:`Width-1` 和 `Height-1` 避免边缘裁剪 3. **资源管理** ```csharp // 使用 using 确保资源释放 using (Pen myPen = new Pen(Color.Red)) { g.DrawRectangle(myPen, ...); } ``` #### 完整示例:渐变背景控件 ```csharp public class GradientUserControl : UserControl { public Color StartColor { get; set; } = Color.Blue; public Color EndColor { get; set; } = Color.White; public GradientUserControl() { SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); using (LinearGradientBrush brush = new LinearGradientBrush( ClientRectangle, StartColor, EndColor, 45f)) { e.Graphics.FillRectangle(brush, ClientRectangle); } using (Pen borderPen = new Pen(Color.DarkGray, 2)) { e.Graphics.DrawRectangle(borderPen, new Rectangle(0, 0, Width - 1, Height - 1)); } } } ``` #### 常见问题解决 1. **绘制内容不显示** - 确认设置了 `ControlStyles.UserPaint` - 检查是否调用了 `base.OnPaint(e)` - 验证 `Invalidate()` 是否被正确调用 2. **绘制闪烁问题** ```csharp // 添加以下样式设置 SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); ``` 3. **子控件覆盖自定义绘制** - 在 `OnPaint` 中最后绘制覆盖层内容 - 使用 `BringToFront()`/`SendToBack()` 调整控件层级 #### 性能优化建议 1. 避免在 `OnPaint` 中创建资源对象 2. 复杂绘制使用缓存 Bitmap: ```csharp private Bitmap _cachedBitmap; protected override void OnPaint(PaintEventArgs e) { if (_cachedBitmap == null || _cachedBitmap.Size != Size) { _cachedBitmap = new Bitmap(Width, Height); using (Graphics bg = Graphics.FromImage(_cachedBitmap)) { // 绘制到缓存位图 } } e.Graphics.DrawImage(_cachedBitmap, 0, 0); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值