轉(zhuǎn)帖|其它|編輯:郝浩|2011-09-16 14:00:23.000|閱讀 3661 次
概述:最近做一個圖象的采集,需要一個圖形的選擇控件,但是在.net下沒有類似vb中的shape控件,所以考慮了自己寫一個控件。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
最近做一個圖象的采集,需要一個圖形的選擇控件,但是在.net下沒有類似vb中的shape控件,所以考慮了自己寫一個控件。
下面我將從頭創(chuàng)建控件,這個控件主要是用來選擇圖形的Rectangle,有一下幾個屬性Color BorderColor:邊框顏色,Color BackColor:背景顏色,bool ReSizeble:是否可移動, Rectangle SelectRectangle:選擇區(qū)域。
打開vs2003(我用的這個版本),新建一個c#控件庫,ok,拷貝如下代碼到你的代碼里。
u?s?i?n?g ?S?y?s?t?e?m?;?
u?s?i?n?g ?S?y?s?t?e?m?.?C?o?l?l?e?c?t?i?o?n?s?;?
u?s?i?n?g ?S?y?s?t?e?m?.?C?o?m?p?o?n?e?n?t?M?o?d?e?l?;?
u?s?i?n?g ?S?y?s?t?e?m?.?D?r?a?w?i?n?g?;?
u?s?i?n?g ?S?y?s?t?e?m?.?D?a?t?a?;?
u?s?i?n?g ?S?y?s?t?e?m?.?W?i?n?d?o?w?s?.?F?o?r?m?s?;?
n?a?m?e?s?p?a?c?e ?W?i?n?d?o?w?s?E?x?t?e?n?d?e?d?C?o?n?t?r?o?l?s?
{?
/?/?/ <?s?u?m?m?a?r?y?>
/?/?/ ?控?件?
/?/?/ <?/?s?u?m?m?a?r?y?>
p?u?b?l?i?c c?l?a?s?s ?S?h?a?p?e?E?x? ?:? ?S?y?s?t?e?m?.?W?i?n?d?o?w?s?.?F?o?r?m?s?.?C?o?n?t?r?o?l?
{?
/?/?/ <?s?u?m?m?a?r?y?>
/?/?/ ?必?需?的?設?計?器?變?量?。?
/?/?/ <?/?s?u?m?m?a?r?y?>
/?/?/
p?r?i?v?a?t?e ?C?o?l?o?r? ?_?B?o?r?d?e?r?C?o?l?o?r=n?e?w ?C?o?l?o?r?(?)?;?
p?r?i?v?a?t?e ?C?o?l?o?r? ?_?B?a?c?k?C?o?l?o?r=n?e?w ?C?o?l?o?r?(?)?;?
p?r?i?v?a?t?e b?o?o?l ?_?R?e?S?i?z?e?b?l?e?;?
p?r?i?v?a?t?e ?P?o?i?n?t? ?_?S?e?l?f?L?o?c?a?t?i?o?n=n?e?w ?P?o?i?n?t?(?)?;?
p?r?i?v?a?t?e ?P?o?i?n?t? ?_?M?o?u?s?e?L?o?c?a?t?i?o?n=n?e?w ?P?o?i?n?t?(?)?;?
p?r?i?v?a?t?e i?n?t ?_?S?e?l?f?W?i?d?t?h?;?
p?r?i?v?a?t?e i?n?t ?_?S?e?l?f?H?e?i?g?h?t?;?
p?r?i?v?a?t?e i?n?t ?_?S?e?l?e?c?t?S?e?l?c?t?e?d?I?n?d?e?x?;/?/0?-?8?,?0?:?S?i?z?e?A?l?l
p?r?i?v?a?t?e 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()
{
// 該調(diào)用是 Windows.Forms 窗體設計器所必需的。
InitializeComponent();
// TODO: 在 InitComponent 調(diào)用后添加任何初始化
}
[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("控件選擇區(qū)域"),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>
/// 設計器支持所需的方法 - 不要使用代碼編輯器
/// 修改此方法的內(nèi)容。
/// </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;
}
}
} 下面講一下控件具體如何工作,首先要寫他的屬性以及重寫他的屬性:
p?r?i?v?a?t?e ?C?o?l?o?r? ?_?B?o?r?d?e?r?C?o?l?o?r=n?e?w ?C?o?l?o?r?(?)?;?
[?D?e?f?a?u?l?t?V?a?l?u?e?("B?l?a?c?k")?,?D?e?s?c?r?i?p?t?i?o?n?("邊?框?顏?色")?,?
C?a?t?e?g?o?r?y?("A?p?p?e?a?r?a?n?c?e")?]? ?
p?u?b?l?i?c ?C?o?l?o?r? ?B?o?r?d?e?r?C?o?l?o?r?
{?
g?e?t
{
// Insert code here.
return _BorderColor;
}
set
{
_BorderColor=value;
this.Invalidate();
}
} DefaultValue:設定默認值,Description:描述,就是屬性下面的說明,Category:屬性分類.其他的同理
設置好屬性以后應該重寫他的繪制過程,也就是: p?r?o?t?e?c?t?e?d o?v?e?r?r?i?d?e v?o?i?d ?O?n?P?a?i?n?t?(?P?a?i?n?t?E?v?e?n?t?A?r?g?s? ?p?e?)?
{?
/?/ ?C?a?l?l?i?n?g? ?t?h?e? ?b?a?s?e? ?c?l?a?s?s? ?O?n?P?a?i?n?t
b?a?s?e.?O?n?P?a?i?n?t?(?p?e?)?;?
R?e?D?r?a?w?C?o?n?t?r?o?l?(?p?e?.?G?r?a?p?h?i?c?s?)?;?
}?
p?r?i?v?a?t?e v?o?i?d ?R?e?D?r?a?w?C?o?n?t?r?o?l?(?G?r?a?p?h?i?c?s? ?g?r?a?p?h?i?c?s?)?
{?
t?r?y
{?
/?/繪?制?邊?框? ? ? ?
R?e?c?t?a?n?g?l?e? ?r?e?c?t?B?o?r?d?e?r=n?e?w ?R?e?c?t?a?n?g?l?e?(?)?;?
P?e?n? ?b?o?r?d?e?r?P?e?n=n?e?w ?P?e?n?(t?h?i?s.?_?B?o?r?d?e?r?C?o?l?o?r?,1)?;?
r?e?c?t?B?o?r?d?e?r?.?X? = 7;?
r?e?c?t?B?o?r?d?e?r?.?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("控件選擇區(qū)域"),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函數(shù)了,先添加事件:
? ? t?h?i?s.?R?e?s?i?z?e? +?= n?e?w ?S?y?s?t?e?m?.?E?v?e?n?t?H?a?n?d?l?e?r?(t?h?i?s.?S?h?a?p?e?E?x?_?R?e?s?i?z?e?)?;?
t?h?i?s.?M?o?u?s?e?U?p? +?= n?e?w ?S?y?s?t?e?m?.?W?i?n?d?o?w?s?.?F?o?r?m?s?.?M?o?u?s?e?E?v?e?n?t?H?a?n?d?l?e?r?(t?h?i?s.?S?h?a?p?e?E?x?_?M?o?u?s?e?U?p?)?;?
t?h?i?s.?M?o?u?s?e?M?o?v?e? +?= n?e?w ?S?y?s?t?e?m?.?W?i?n?d?o?w?s?.?F?o?r?m?s?.?M?o?u?s?e?E?v?e?n?t?H?a?n?d?l?e?r?(t?h?i?s.?S?h?a?p?e?E?x?_?M?o?u?s?e?M?o?v?e?)?;?
t?h?i?s.?M?o?u?s?e?L?e?a?v?e? +?= n?e?w System.EventHandler(this.ShapeEx_MouseLeave);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ShapeEx_MouseDown);
原理:當鼠標點擊的時候this.MouseDown,記錄鼠標的位置,控件的原始位置和大小,判斷位 置:_rectLeftBottomSelector.Contains(e.X,e.Y):表示點擊的是左下,設置鼠標,記錄狀態(tài) this._SelectSelctedIndex:判斷點擊了那個選擇框,取值0-8:0代表移動整個控件,1是右上移動,2-8順時針索引選擇框。 this.MouseMove處理如何改變控件的大小和位置 c?a?s?e 0:/?/只?移?動?位?置
c?a?s?e 0:/?/只?移?動?位?置
? ? ? ? t?h?i?s.?L?o?c?a?t?i?o?n=n?e?w ?P?o?i?n?t?(?C?u?r?s?o?r?.?P?o?s?i?t?i?o?n?.?X-(?_?M?o?u?s?e?L?o?c?a?t?i?o?n?.?X-_?S?e?l?f?L?o?c?a?t?i?o?n?.?X?)?,?C?u?r?s?o?r?.?P?o?s?i?t?i?o?n?.?Y-(?_?M?o?u?s?e?L?o?c?a?t?i?o?n?.?Y-_?S?e?l?f?L?o?c?a?t?i?o?n?.?Y?)?)?;?
? ? ? ? b?r?e?a?k;
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡轉(zhuǎn)載