主页 > 编程资料 > C# >
发布时间:2015-09-26 作者:网络 阅读:252次

最近做一个图象的采集,需要一个图形的选择控件,但是在.net下没有类似vb中的shape控件,所以考虑了自己写一个控件。

下面我将从头创建控件,这个控件主要是用来选择图形的Rectangle,有一下几个属性Color BorderColor:边框颜色,Color BackColor:背景颜色,bool ReSizeble:是否可移动, Rectangle SelectRectangle:选择区域。
打开vs2003(我用的这个版本),新建一个c#控件库,ok,拷贝如下代码到你的代码里。

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace WindowsExtendedControls
{
 /// <summary>
 /// 控件
 /// </summary>
 public class ShapeEx : System.Windows.Forms.Control
 {
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  /// 
  private Color _BorderColor=new Color(,',',');
  private Color _BackColor=new Color(,',',');
  private bool _ReSizeble;
  private Point _SelfLocation=new Point(,',',');
  private Point _MouseLocation=new Point(,',',');
  private int _SelfWidth;
  private int _SelfHeight;
  private int _SelectSelctedIndex;//0-8,0:SizeAll
  private Rectangle _rectLeftSelector=new Rectangle(,',',');
  private Rectangle _rectTopSelector=new Rectangle(,',',');
  private Rectangle _rectRightSelector=new Rectangle(,',',');
  private Rectangle _rectBottomSelector=new Rectangle(,',',');
  private Rectangle _rectLeftTopSelector=new Rectangle(,',',');
  private Rectangle _rectRightTopSelector=new Rectangle(,',',');
  private Rectangle _rectRightBottomSelector=new Rectangle(,',',');
  private Rectangle _rectLeftBottomSelector=new Rectangle(,',',');
  private System.ComponentModel.Container components = null;
  public ShapeEx()
  {
   // 该调用是 Windows.Forms 窗体设计器所必需的。
   InitializeComponent(,',',');
   // TODO: 在 InitComponent 调用后添加任何初始化
  }
  [DefaultValue("Black"),Description("边框颜色"),Category("Appearance")] 
  public Color BorderColor
  {
   get 
   {
    // Insert code here.
    return _BorderColor;
   }
   set 
   {
    _BorderColor=value;
    this.Invalidate(,',',');
   }
  }
  [DefaultValue("Control"),Description("背景颜色"),Category("Appearance")] 
  public override Color BackColor
  {
   get 
   {
    // Insert code here.
    return _BackColor;
   }
   set 
   {
    _BackColor=value;
    this.Invalidate(,',',');
   }
  }
  [DefaultValue(false),Description("运行中控件大小是否可拖拽编辑"),Category("Behavior")] 
  public  bool ReSizeble
  {
   get 
   {
    // Insert code here.
    return _ReSizeble;
   }
   set 
   {
    _ReSizeble=value;
    this.Invalidate(,',',');
   }
  }
  [Description("控件选择区域"),Category("Behavior")] 
  public  Rectangle SelectRectangle
  {
   get 
   {
    Rectangle selectRectangler=new Rectangle(,',',');
    selectRectangler.X = this.Location.X+7;
    selectRectangler.Y = this.Location.Y+7;
    selectRectangler.Height = this.Height-15;
    selectRectangler.Width = this.Width-15;
    return selectRectangler;
   }
  
  }
 
  protected override void OnPaint(PaintEventArgs pe)
  {
   // Calling the base class OnPaint
   base.OnPaint(pe,',',');
   ReDrawControl(pe.Graphics,',',');
  }
  private void DrawSelector(Graphics graphics)
  {
   SolidBrush SelectorPen=new SolidBrush(Color.White,',',');
   Pen borderPen=new Pen(this._BorderColor,1,',',');
   try
   {
    //实心
    PointF[] LeftPoints=getPointF(0,this.Height/2-3,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, LeftPoints,',',');
    PointF[] TopPoints=getPointF(this.Width/2-3,0,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, TopPoints,',',');
    PointF[] RightPoints=getPointF(this.Width-7,this.Height/2-3,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, RightPoints,',',');
    PointF[] BottomPoints=getPointF(this.Width/2-3,this.Height-7,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, BottomPoints,',',');
    PointF[] LeftTopPoints=getPointF(0,0,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, LeftTopPoints,',',');
    PointF[] RightTopPoints=getPointF(this.Width-7,0,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, RightTopPoints,',',');
    PointF[] RightBottomPoints=getPointF(this.Width-7,this.Height-7,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, RightBottomPoints,',',');
    
    PointF[] LeftBottomPoints=getPointF(0,this.Height-7,6,6,',',');
    graphics.FillClosedCurve(SelectorPen, LeftBottomPoints,',',');
    //边框
    _rectLeftSelector.X = 0;
    _rectLeftSelector.Y = this.Height/2-3;
    _rectLeftSelector.Height = 6;
    _rectLeftSelector.Width = 6;
    graphics.DrawRectangle(borderPen, _rectLeftSelector,',',');
    _rectTopSelector.X = this.Width/2-3;
    _rectTopSelector.Y = 0;
    _rectTopSelector.Height = 6;
    _rectTopSelector.Width = 6;
    graphics.DrawRectangle(borderPen, _rectTopSelector,',',');
    _rectRightSelector.X = this.Width-7;
    _rectRightSelector.Y = this.Height/2-3;
    _rectRightSelector.Height = 6;
    _rectRightSelector.Width = 6;
    graphics.DrawRectangle(borderPen, _rectRightSelector,',',');
    _rectBottomSelector.X = this.Width/2-3;
    _rectBottomSelector.Y = this.Height-7;
    _rectBottomSelector.Height = 6;
    _rectBottomSelector.Width = 6;
    graphics.DrawRectangle(borderPen, _rectBottomSelector,',',');
    _rectLeftTopSelector.X=0;
    _rectLeftTopSelector.Y=0;
    _rectLeftTopSelector.Width=6;
    _rectLeftTopSelector.Height=6;
    graphics.DrawRectangle(borderPen, _rectLeftTopSelector,',',');
    _rectRightTopSelector.X=this.Width-7;
    _rectRightTopSelector.Y=0;
    _rectRightTopSelector.Width=6;
    _rectRightTopSelector.Height=6;
    graphics.DrawRectangle(borderPen, _rectRightTopSelector,',',');
    _rectRightBottomSelector.X=this.Width-7;
    _rectRightBottomSelector.Y=this.Height-7;
    _rectRightBottomSelector.Width=6;
    _rectRightBottomSelector.Height=6;
    graphics.DrawRectangle(borderPen, _rectRightBottomSelector,',',');
    _rectLeftBottomSelector.X=0;
    _rectLeftBottomSelector.Y=this.Height-7;
    _rectLeftBottomSelector.Width=6;
    _rectLeftBottomSelector.Height=6;
    graphics.DrawRectangle(borderPen, _rectLeftBottomSelector,',',');
   }
   catch(Exception E)
   {
    throw E;
   }
   finally
   {
    SelectorPen.Dispose(,',',');
    borderPen.Dispose(,',',');
   }
    
  }
  private void ReDrawControl(Graphics graphics)
  {
   
   try
   {
   
    //绘制背景
    /*
    graphics.Clear(this._BackColor,',',');
    SolidBrush backPen=new SolidBrush(this._BackColor,',',');
    PointF point1 = new PointF(1,1,',',');
    PointF point2 = new PointF(this.Width-2,1,',',');
    PointF point3 = new PointF(this.Width-2,this.Height-2,',',');
    PointF point4 = new PointF(1,this.Height-2,',',');
    PointF[] points = {point1, point2, point3, point4};
    graphics.FillClosedCurve(backPen, points,',',');
    */
    //绘制边框    
    Rectangle rectBorder=new Rectangle(,',',');
    Pen borderPen=new Pen(this._BorderColor,1,',',');
    rectBorder.X = 7;
    rectBorder.Y = 7;
    rectBorder.Height = this.Height-15;
    rectBorder.Width = this.Width-15;
    graphics.DrawRectangle(borderPen, rectBorder,',',');
    //绘制编辑框
    if (_ReSizeble)
    {
     DrawSelector(graphics,',',');
    }
   }
   catch(Exception E)
   {
    throw E;
   }
   finally
   {
    graphics.Dispose(,',',');
   }
  }
  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  private PointF[] getPointF(int x,int y,int Width,int Height){
   PointF point1 = new PointF(x,y,',',');
   PointF point2 = new PointF(x+Width,y,',',');
   PointF point3 = new PointF(x+Width,y+Height,',',');
   PointF point4 = new PointF(x,y+Height,',',');
   PointF[] points = {point1, point2, point3, point4};
   return points;
  }
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if( components != null )
     components.Dispose(,',',');
   }
   base.Dispose( disposing ,',',');
  }
  #region 组件设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器 
  /// 修改此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {
   components = new System.ComponentModel.Container(,',',');
   this.Resize+=new EventHandler(ShapeEx_Resize,',',');
   this.MouseDown+=new MouseEventHandler(ShapeEx_MouseDown,',',');
   this.MouseMove+=new MouseEventHandler(ShapeEx_MouseMove,',',');
   this.MouseLeave+=new EventHandler(ShapeEx_MouseLeave,',',');
   this.MouseUp+=new MouseEventHandler(ShapeEx_MouseUp,',',');
   this._BorderColor=Color.Black;
   this._BackColor=Color.FromName("Control",',',');
   this._ReSizeble=false;
   this._SelectSelctedIndex=-1;
   SetStyle(ControlStyles.SupportsTransparentBackColor, true,',',');
  }
  #endregion
  private void ShapeEx_Resize(object sender, EventArgs e)
  {
   if (this.Width<16 || this.Height<16)
   {
    this.Width=16;
    this.Height=16;
   }
   this.Invalidate(,',',');
  }
 
  private void ShapeEx_MouseDown(object sender, MouseEventArgs e)
  {
   if (_ReSizeble)
   {
   
 if (_rectLeftSelector.Contains(e.X,e.Y) || 
_rectRightSelector.Contains(e.X,e.Y) || 
_rectTopSelector.Contains(e.X,e.Y) || 
_rectBottomSelector.Contains(e.X,e.Y) 
||_rectLeftTopSelector.Contains(e.X,e.Y) || 
_rectRightTopSelector.Contains(e.X,e.Y) || 
_rectRightBottomSelector.Contains(e.X,e.Y) || 
_rectLeftBottomSelector.Contains(e.X,e.Y))
    {
     if (_rectLeftTopSelector.Contains(e.X,e.Y) )
     {
      this.Cursor=Cursors.SizeNWSE;
      this._SelectSelctedIndex=1;
     }
     
     if (_rectTopSelector.Contains(e.X,e.Y) )
     {
      this.Cursor=Cursors.SizeNS;
      this._SelectSelctedIndex=2;
     }
     if (_rectRightTopSelector.Contains(e.X,e.Y) )
     {
      this.Cursor=Cursors.SizeNESW;
      this._SelectSelctedIndex=3;
     }
     if (_rectRightSelector.Contains(e.X,e.Y) )
     {
      this.Cursor=Cursors.SizeWE;
      this._SelectSelctedIndex=4;
     }
     if (_rectRightBottomSelector.Contains(e.X,e.Y) )
     {
      this.Cursor=Cursors.SizeNWSE;
      this._SelectSelctedIndex=5;
     }
     if (_rectBottomSelector.Contains(e.X,e.Y))
     {
      this.Cursor=Cursors.SizeNS;
      this._SelectSelctedIndex=6;
     }
     if (_rectLeftBottomSelector.Contains(e.X,e.Y) )
     {
      this.Cursor=Cursors.SizeNESW;
      this._SelectSelctedIndex=7;
     }
     if (_rectLeftSelector.Contains(e.X,e.Y))
     {
      this.Cursor=Cursors.SizeWE;
      this._SelectSelctedIndex=8;
     }
    }
    else
    {
     this.Cursor=Cursors.SizeAll;
     this._SelectSelctedIndex=0;
    }
    this._SelfLocation.X=this.Location.X;
    this._SelfLocation.Y=this.Location.Y;
    this._MouseLocation.X=Cursor.Position.X;
    this._MouseLocation.Y=Cursor.Position.Y;
    this._SelfWidth=this.Width;
    this._SelfHeight=this.Height;
   }
  }
  private void ShapeEx_MouseMove(object sender, MouseEventArgs e)
  {
   //move and resize
   switch (this._SelectSelctedIndex)
   {
    case 0:
    
 this.Location=new 
Point(Cursor.Position.X-(_MouseLocation.X-_SelfLocation.X),Cursor.Position.Y-(_MouseLocation.Y-_SelfLocation.Y),',',');
     break;
    case 1:
     this.Height=this._SelfHeight-(Cursor.Position.Y-_MouseLocation.Y,',',');
     this.Width=this._SelfWidth-(Cursor.Position.X-_MouseLocation.X,',',');
    
 this.Location=new 
Point(Cursor.Position.X-_MouseLocation.X+_SelfLocation.X,Cursor.Position.Y-_MouseLocation.Y+_SelfLocation.Y,',',');
     break;
    case 2:
     this.Height=this._SelfHeight-(Cursor.Position.Y-_MouseLocation.Y,',',');
     this.Location=new Point(_SelfLocation.X,Cursor.Position.Y-_MouseLocation.Y+_SelfLocation.Y,',',');
     break;
    case 3:
     this.Height=this._SelfHeight-(Cursor.Position.Y-_MouseLocation.Y,',',');
     this.Width=this._SelfWidth+(Cursor.Position.X-_MouseLocation.X,',',');
     this.Location=new Point(_SelfLocation.X,Cursor.Position.Y-(_MouseLocation.Y-_SelfLocation.Y),',',');
     break;
    case 4:
     this.Width=this._SelfWidth+(Cursor.Position.X-_MouseLocation.X,',',');
     break;
    case 5:
     this.Height=this._SelfHeight+(Cursor.Position.Y-_MouseLocation.Y,',',');
     this.Width=this._SelfWidth+(Cursor.Position.X-_MouseLocation.X,',',');
     break;
    case 6:
     this.Height=this._SelfHeight+(Cursor.Position.Y-_MouseLocation.Y,',',');
     break;
    case 7:
     this.Height=this._SelfHeight+(Cursor.Position.Y-_MouseLocation.Y,',',');
     this.Width=this._SelfWidth-(Cursor.Position.X-_MouseLocation.X,',',');
     this.Location=new Point(Cursor.Position.X-_MouseLocation.X+_SelfLocation.X,_SelfLocation.Y,',',');
     break;
    case 8:
     this.Width=this._SelfWidth-(Cursor.Position.X-_MouseLocation.X,',',');
     this.Location=new Point(Cursor.Position.X-_MouseLocation.X+_SelfLocation.X,_SelfLocation.Y,',',');
     break;
   }
  }
  private void ShapeEx_MouseLeave(object sender, EventArgs e)
  {
   this.Cursor=Cursors.Default;
   this._SelectSelctedIndex=-1;
  }
  private void ShapeEx_MouseUp(object sender, MouseEventArgs e)
  {
   this.Cursor=Cursors.Default;
   this._SelectSelctedIndex=-1;
  }
 }
}


 


 

下面讲一下控件具体如何工作,首先要写他的属性以及重写他的属性,

private Color _BorderColor=new Color(,',',');
 [DefaultValue("Black"),Description("边框颜色"),Category("Appearance")] 
  public Color BorderColor
  {
   get 
   {
    // Insert code here.
    return _BorderColor;
   }
   set 
   {
    _BorderColor=value;
    this.Invalidate(,',',');
   }
  }


DefaultValue:设定默认值,Description:描述,就是属性下面的说明,Category:属性分类.其他的同理
设置好属性以后应该重写他的绘制过程,也就是

protected override void OnPaint(PaintEventArgs pe)
  {
   // Calling the base class OnPaint
   base.OnPaint(pe,',',');
   ReDrawControl(pe.Graphics,',',');
  }
 private void ReDrawControl(Graphics graphics)
  {
   
   try
   {
    //绘制边框    
    Rectangle rectBorder=new Rectangle(,',',');
    Pen borderPen=new Pen(this._BorderColor,1,',',');
    rectBorder.X = 7;
    rectBorder.Y = 7;
    rectBorder.Height = this.Height-15;
    rectBorder.Width = this.Width-15;
    graphics.DrawRectangle(borderPen, rectBorder,',',');
    //绘制编辑框
    if (_ReSizeble)
    {
     DrawSelector(graphics,',',');
    }
   }
   catch(Exception E)
   {
    throw E;
   }
   finally
   {
    graphics.Dispose(,',',');
   }
  }
 [Description("控件选择区域"),Category("Behavior")] 
  public  Rectangle SelectRectangle
  {
   get 
   {
    Rectangle selectRectangler=new Rectangle(,',',');
    selectRectangler.X = this.Location.X+7;
    selectRectangler.Y = this.Location.Y+7;
    selectRectangler.Height = this.Height-15;
    selectRectangler.Width = this.Width-15;
    return selectRectangler;
   }
  
  }


ReDrawControl中定义了Rectangle (矩形),让后填充改矩形的边框:graphics.DrawRectangle(borderPen, rectBorder,',',');,这里要说明的是边框外面还有编辑框,所以大小不是控件的大小。DrawSelector就是绘制8个选择框的,基本和绘制边框差不多,即使定义好坐标就可以了。干好了之后不要忘了释放资源:graphics.Dispose(,',',');

SelectRectangle:控件所选择的Rectangle,最终要得就是它了

ok,这样一个基本的东西出来了,下面我们要写他的move和resize函数了,先添加事件:

this.Resize += new System.EventHandler(this.ShapeEx_Resize,',',');
   this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ShapeEx_MouseUp,',',');
   this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ShapeEx_MouseMove,',',');
   this.MouseLeave += new System.EventHandler(this.ShapeEx_MouseLeave,',',');
   this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ShapeEx_MouseDown,',',');


原理:当鼠标点击的时候this.MouseDown,记录鼠标的位置,控件的原始位置和大小,判断位置:_rectLeftBottomSelector.Contains(e.X,e.Y):表示点击的是左下,设置鼠标,记录状态this._SelectSelctedIndex:判断点击了那个选择框,取值0-8:0代表移动整个控件,1是右上移动,2-8顺时针索引选择框。this.MouseMove处理如何改变控件的大小和位置
case 0://只移动位置
     this.Location=new Point(Cursor.Position.X-(_MouseLocation.X-_SelfLocation.X),Cursor.Position.Y-(_MouseLocation.Y-_SelfLocation.Y),',',');
     break;
1,5不仅移动位置,还改变大小,2,3,4,6,7,8只改变大小

其他则是清理工作。

好了,那么赶紧编译。生成就可以了。


关键字词: