创建ImageButton自定义控件

*本文大部分都参考了MSDN的文章,非原创

在创建自行绘制的控件时,应从 System.Windows.Forms.Control 中派生,并覆盖 OnPaintOnPaintBackground 事件。 下面是一个最简单的例子:
 1 None.gif using  System;
 2 None.gif using  System.Collections.Generic;
 3 None.gif using  System.ComponentModel;
 4 None.gif using  System.Data;
 5 None.gif using  System.Drawing;
 6 None.gif using  System.Text;
 7 None.gif using  System.Windows.Forms;
 8 None.gif
 9 None.gif namespace  Animation
10 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
11InBlock.gif    public partial class ImageButton : Control
12ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
13InBlock.gif        private Image image;
14InBlock.gif
15InBlock.gif        public ImageButton()
16ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
17InBlock.gif            InitializeComponent();
18ExpandedSubBlockEnd.gif        }

19InBlock.gif
20InBlock.gif        public Image Image
21ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
22ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn this.image; }
23ExpandedSubBlockStart.gifContractedSubBlock.gif            set dot.gifthis.image = value; }
24ExpandedSubBlockEnd.gif        }

25InBlock.gif
26InBlock.gif        protected override void OnPaint(PaintEventArgs pe)
27ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
28InBlock.gif            if (image != null)
29ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
30InBlock.gif                Graphics g = pe.Graphics;
31InBlock.gif                g.DrawImage(image, this.ClientRectangle);
32ExpandedSubBlockEnd.gif            }

33InBlock.gif
34InBlock.gif            // 调用基类 OnPaint
35InBlock.gif            base.OnPaint(pe);
36ExpandedSubBlockEnd.gif        }

37InBlock.gif
38InBlock.gif        protected override void OnPaintBackground(PaintEventArgs pevent)
39ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
40InBlock.gif            base.OnPaintBackground(pevent);
41ExpandedSubBlockEnd.gif        }

42ExpandedSubBlockEnd.gif    }

43ExpandedBlockEnd.gif}

44 None.gif

当然,现在这个ImageButton除了能显示一张图片以外什么也不能做,我将在后面一步一步完善它。
OnPaint 事件的特性是它可以根据操作系统的要求无限次调用。在实例化和销毁这些对象上浪费时间将会影响绘图性能。 出现所谓的“闪烁”现象,通常采用“双缓冲”来减小这一因素的影响:
None.gif private  Bitmap imageBuffer;
None.gif
None.gif
protected   override   void  OnPaint(PaintEventArgs e)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Graphics gBuffer;      
//屏幕外的图像
InBlock.gif
    Rectangle imageRect; //图像矩形
InBlock.gif
InBlock.gif    
//在内存中绘制位图
InBlock.gif
    if (imageBuffer == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        imageBuffer 
= new Bitmap(ClientSize.Width, ClientSize.Height);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    imageRect 
= this.ClientRectangle;
InBlock.gif    gBuffer 
= Graphics.FromImage(imageBuffer);
InBlock.gif
InBlock.gif    gBuffer.Clear(
this.BackColor);  //清除绘图面并以背景色填充
InBlock.gif
    gBuffer.DrawImage(this.Image, 00, imageRect, GraphicsUnit.Pixel);
InBlock.gif
InBlock.gif    
//从内存位图绘制
InBlock.gif
    e.Graphics.DrawImage(imageBuffer, 00);
InBlock.gif
InBlock.gif    
base.OnPaint(e);
ExpandedBlockEnd.gif}
在上面的代码中,我们通过调用 Graphics 类的静态 FromImage 方法在与我们的控件大小相同的空位图中创建了一个 Graphics 对象。我们在内存中的 Graphics 对象上进行所有的绘图,完成后,将整个准备好的位图覆盖到控件的图形上即可。源代码如下:
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.ComponentModel;
None.gif
using  System.Data;
None.gif
using  System.Drawing;
None.gif
using  System.Text;
None.gif
using  System.Windows.Forms;
None.gif
None.gif
namespace  Animation
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public partial class ImageButton : Control
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private Image image;
InBlock.gif        
private bool bePushsd;
InBlock.gif        
private Bitmap imageBuffer;
InBlock.gif
InBlock.gif        
public ImageButton()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.Size = new Size(100100);
InBlock.gif            bePushsd 
= false;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public Image Image
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn this.image; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gifthis.image = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override void OnPaint(PaintEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Graphics gBuffer; 
InBlock.gif            Rectangle imageRect; 
//图像矩形
InBlock.gif
            Brush backBrush;
InBlock.gif
InBlock.gif            
//在内存中绘制位图
InBlock.gif
            if (imageBuffer == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                imageBuffer 
= new Bitmap(ClientSize.Width, ClientSize.Height);
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            gBuffer 
= Graphics.FromImage(imageBuffer);
InBlock.gif
InBlock.gif            gBuffer.Clear(
this.BackColor);  //清除绘图面并以背景色填充
InBlock.gif

InBlock.gif            
if (!bePushsd)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                backBrush 
= new SolidBrush(Parent.BackColor);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                backBrush 
= new SolidBrush(Color.LightGray);
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            gBuffer.FillRectangle(backBrush, 
this.ClientRectangle);
InBlock.gif
InBlock.gif            
if (this.Image != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                int imageLeft = (this.Width - this.Image.Width) / 2;
InBlock.gif                int imageTop = (this.Height - this.Image.Height) / 2;
InBlock.gif
InBlock.gif                if (!bePushsd)
ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
InBlock.gif                    imageRect = new Rectangle(imageLeft, imageTop, this.Image.Width, this.Image.Height);
ExpandedSubBlockEnd.gif                }
InBlock.gif                else
ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
InBlock.gif                    imageRect = new Rectangle(imageLeft + 2, imageTop + 2, this.Image.Width, this.Image.Height);
ExpandedSubBlockEnd.gif                }
InBlock.gif
InBlock.gif                gBuffer.DrawImage(this.Image, imageRect, 0, 0, this.Image.Width, this.Image.Height, GraphicsUnit.Pixel);
ExpandedSubBlockEnd.gif            }
InBlock.gif
InBlock.gif
InBlock.gif            
//从内存位图绘制
InBlock.gif
            e.Graphics.DrawImage(imageBuffer, 00);
InBlock.gif
InBlock.gif            
base.OnPaint(e);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override void OnPaintBackground(PaintEventArgs pevent)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
base.OnPaintBackground(pevent);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override void OnMouseDown(MouseEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            bePushsd 
= true;
InBlock.gif            
this.Invalidate();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override void OnMouseUp(MouseEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            bePushsd 
= false;
InBlock.gif            
this.Invalidate();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

然而,陈现在控件上的一张图片,我们如何让其显示透明图像,为了使图像透明,我们使用下面这个函数来获取图片的背景颜色:
None.gif private  Color ImageBackColor(Image image)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return (new Bitmap(image)).GetPixel(00);
ExpandedBlockEnd.gif}
然后使用 ImageAttributes类的public void SetColorKey(Color colorLow, Color colorHigh) 方法设置透明键值,此方法设置高低颜色键值,以便颜色范围可以成为透明的。对于任何颜色,只要它的三种颜色成分(红、绿、蓝)都处于高低颜色键的对应成分之间,它的颜色就会成为透明的。在使用该类首先要添加如下命名空间:
None.gif using  System.Drawing.Imaging;
要使用该方法,将上面的红颜色代码改为如下即可:
ImageAttributes imageAttr  =   new  ImageAttributes();
imageAttr.SetColorKey(ImageBackColor(
this .Image), ImageBackColor( this .Image));

gBuffer.DrawImage(
this .Image, imageRect,  0 0 this .Image.Width,  this .Image.Height, GraphicsUnit.Pixel,imageAttr);

这只是一个示例,还有很多不足之处,读者可以自己对其进行扩展,如加入Attributes的支持、为图片在控件中的陈现提供不同的方式(如当图片大于控件的尺寸时,是否对图片进行缩放)等。


转载于:https://www.cnblogs.com/nihgwu/archive/2006/07/17/452979.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值