Visual可以開發兩種不同類型的自定義控件:用戶控件(或組合控件)和定制控件:
用戶或組合控件:這種控件根據現有控件的功能創建一個新的控件。這類控件一般用於把控件的用戶界面和功能封裝在一起或者把幾個其它控件組合在一起,改善控件的界面。
定製控件:當沒有控件可以滿足要求時,就創建這類控件,即從頭開始創建控件。
用戶控件繼承於System.Windows.Forms.UserControl
定制控件通常派生於System.Windows.Froms.Control類。
下邊用"創建LabelTexBoxt控件"例子進行學習(其中包含 創建枚舉類型屬性的方法及控件中自定事件的方法):
控件主要功能:
1、Label相對TextBox控件位置可以變更
2、可變更Lbl與Text控件的內容
3、Text可以調用Kepress、KeyDown、及KeyUp事件
4、帶有一個自定議事件
控件中Label相對於TextBox的四種效果:
方法如下:
一、新建ControlLibrary
二、新加兩個Label和TexBox控件
Label一:
Name:lblPosition
Location:0, 0
Label二:
Name:lbl
TextBox:
Name:txt
三、編寫代碼:
namespace TxtUnit
{
public partial class LblTxt : UserControl
{
/// <summary>
/// 自定義事件,在本程序中並沒什麼作用,只是為了學習在自義控件中如何自定義事件
/// </summary>
[Description("自定義事件,當Label相對Text控件的位置改變時")]
public event System.EventHandler PositionChanged;
public LblTxt()
{
InitializeComponent();
#region txt控件事件
txt.KeyDown += new KeyEventHandler(txt_KeyDown);
txt.KeyPress += new KeyPressEventHandler(txt_KeyPress);
txt.KeyUp += new KeyEventHandler(txt_KeyUp);
#endregion
}
#region 設置Text控件中KeyDown、KeyPress、KeyUp為整個控件的KeyDown、KeyPress、KeyUp事件
void txt_KeyDown(object sender, KeyEventArgs e)
{
OnKeyDown(e);
}
void txt_KeyPress(object sender, KeyPressEventArgs e)
{
OnKeyPress(e);
}
void txt_KeyUp(object sender, KeyEventArgs e)
{
//使用控件的KeyUp事件。即控件的KeyUp事件會引發此控件中的Txt 的KeyUp事件
OnKeyUp(e);
}
#endregion
/// <summary>
/// 控件加載時事件方法(控件放天窗體上時將調用這個事件)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void LblTxt_Load(object sender, EventArgs e)
{
//this.Height = txt.Height > lbl.Height ? txt.Height : lbl.Height;
LabelPositionMove();
}
/// <summary>
/// 控件大小改變時事件方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void LblTxt_SizeChanged(object sender, EventArgs e)
{
LabelPositionMove();
}
#region Attribute
/// <summary>
/// 定義LabelText屬性變量
/// </summary>
private string slabelText = "";
/// <summary>
/// 定義LabelText屬性
/// </summary>
[Description("Label的Text值")]
public string LabelText
{
get
{
return slabelText;
}
set
{
slabelText = value;
lbl.Text = slabelText;
LabelPositionMove();
}
}
/// <summary>
/// 定義TextBoxText屬性變量
/// </summary>
private string sTextBoxText = "";
/// <summary>
/// 定義TextBoxtText屬性
/// </summary>
[Description("TextBox的Text值")]
public string TextBoxText
{
get
{
return sTextBoxText;
}
set
{
sTextBoxText = value;
txt.Text = sTextBoxText;
}
}
#endregion
/// <summary>
/// 定義枚舉(用於列出位置)
/// </summary>
public enum PositionEnum
{
Left,
Right,
Up,
Down
}
/// <summary>
/// Label位置屬性變量(枚舉類型)
/// </summary>
private PositionEnum pePosition = PositionEnum.Right;
/// <summary>
/// Label位置屬性(此為枚舉類型屬性)
/// </summary>
[Description("label相對於Text位置屬性,默認為Label在Text的右邊")]
public PositionEnum LabelPosition
{
get
{
return pePosition;
}
set
{
pePosition = value;
//注,此地方要上方法。當設置變更時,重設窗體
LabelPositionMove();
if (PositionChanged!=null)
{
PositionChanged(this, new EventArgs());
}
}
}
/// <summary>
/// Label相對於TextBox位置方法
/// </summary>
private void LabelPositionMove()
{
int width = 0;
//lblPosition控件只是作為定位點控件,Location為0,0。暫時自已沒有想出更好的辦法
switch (pePosition)
{
//label居Text左時
case PositionEnum.Left:
lbl.Top = lblPosition.Top+3;
lbl.Left = lblPosition.Left;
txt.Top = lblPosition.Top;
txt.Left = lbl.Right + 3;
width = this.Width - lbl.Width - 3;
txt.Width = width;
this.Height = txt.Height > lbl.Height ? txt.Height : lbl.Height;
break;
//label居Text右時
case PositionEnum.Right:
//設置txt 的水平定位
txt.Left = lblPosition.Left;
//設置txt的垂直定位
txt.Top = lblPosition.Top;
//設置lbl的垂直定位
lbl.Top = lblPosition.Top+3;
width = this.Width - lbl.Width - 3;
txt.Width = width;
//設置lbl的水平定位
lbl.Left = txt.Right + 3;
//設置控件的高度(這樣設置后,控件在窗體就無法調整高度)
this.Height = txt.Height > lbl.Height ? txt.Height : lbl.Height;
break;
//控件在Text的上邊
case PositionEnum.Up:
lbl.Top = lblPosition.Top;
lbl.Left = lblPosition.Left;
txt.Top = lbl.Bottom;
txt.Left = lblPosition.Left;
lbl.Width = this.Width;
txt.Width = this.Width;
this.Height = txt.Height + lbl.Height;
break;
//label在Text的下方時
case PositionEnum.Down:
txt.Top = lblPosition.Top;
txt.Left = lblPosition.Left;
lbl.Top = txt.Bottom;
lbl.Left = lblPosition.Left;
lbl.Width = this.Width;
txt.Width = this.Width;
this.Height = txt.Height + lbl.Height;
break;
default:
break;
}
}
}
}
{
public partial class LblTxt : UserControl
{
/// <summary>
/// 自定義事件,在本程序中並沒什麼作用,只是為了學習在自義控件中如何自定義事件
/// </summary>
[Description("自定義事件,當Label相對Text控件的位置改變時")]
public event System.EventHandler PositionChanged;
public LblTxt()
{
InitializeComponent();
#region txt控件事件
txt.KeyDown += new KeyEventHandler(txt_KeyDown);
txt.KeyPress += new KeyPressEventHandler(txt_KeyPress);
txt.KeyUp += new KeyEventHandler(txt_KeyUp);
#endregion
}
#region 設置Text控件中KeyDown、KeyPress、KeyUp為整個控件的KeyDown、KeyPress、KeyUp事件
void txt_KeyDown(object sender, KeyEventArgs e)
{
OnKeyDown(e);
}
void txt_KeyPress(object sender, KeyPressEventArgs e)
{
OnKeyPress(e);
}
void txt_KeyUp(object sender, KeyEventArgs e)
{
//使用控件的KeyUp事件。即控件的KeyUp事件會引發此控件中的Txt 的KeyUp事件
OnKeyUp(e);
}
#endregion
/// <summary>
/// 控件加載時事件方法(控件放天窗體上時將調用這個事件)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void LblTxt_Load(object sender, EventArgs e)
{
//this.Height = txt.Height > lbl.Height ? txt.Height : lbl.Height;
LabelPositionMove();
}
/// <summary>
/// 控件大小改變時事件方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void LblTxt_SizeChanged(object sender, EventArgs e)
{
LabelPositionMove();
}
#region Attribute
/// <summary>
/// 定義LabelText屬性變量
/// </summary>
private string slabelText = "";
/// <summary>
/// 定義LabelText屬性
/// </summary>
[Description("Label的Text值")]
public string LabelText
{
get
{
return slabelText;
}
set
{
slabelText = value;
lbl.Text = slabelText;
LabelPositionMove();
}
}
/// <summary>
/// 定義TextBoxText屬性變量
/// </summary>
private string sTextBoxText = "";
/// <summary>
/// 定義TextBoxtText屬性
/// </summary>
[Description("TextBox的Text值")]
public string TextBoxText
{
get
{
return sTextBoxText;
}
set
{
sTextBoxText = value;
txt.Text = sTextBoxText;
}
}
#endregion
/// <summary>
/// 定義枚舉(用於列出位置)
/// </summary>
public enum PositionEnum
{
Left,
Right,
Up,
Down
}
/// <summary>
/// Label位置屬性變量(枚舉類型)
/// </summary>
private PositionEnum pePosition = PositionEnum.Right;
/// <summary>
/// Label位置屬性(此為枚舉類型屬性)
/// </summary>
[Description("label相對於Text位置屬性,默認為Label在Text的右邊")]
public PositionEnum LabelPosition
{
get
{
return pePosition;
}
set
{
pePosition = value;
//注,此地方要上方法。當設置變更時,重設窗體
LabelPositionMove();
if (PositionChanged!=null)
{
PositionChanged(this, new EventArgs());
}
}
}
/// <summary>
/// Label相對於TextBox位置方法
/// </summary>
private void LabelPositionMove()
{
int width = 0;
//lblPosition控件只是作為定位點控件,Location為0,0。暫時自已沒有想出更好的辦法
switch (pePosition)
{
//label居Text左時
case PositionEnum.Left:
lbl.Top = lblPosition.Top+3;
lbl.Left = lblPosition.Left;
txt.Top = lblPosition.Top;
txt.Left = lbl.Right + 3;
width = this.Width - lbl.Width - 3;
txt.Width = width;
this.Height = txt.Height > lbl.Height ? txt.Height : lbl.Height;
break;
//label居Text右時
case PositionEnum.Right:
//設置txt 的水平定位
txt.Left = lblPosition.Left;
//設置txt的垂直定位
txt.Top = lblPosition.Top;
//設置lbl的垂直定位
lbl.Top = lblPosition.Top+3;
width = this.Width - lbl.Width - 3;
txt.Width = width;
//設置lbl的水平定位
lbl.Left = txt.Right + 3;
//設置控件的高度(這樣設置后,控件在窗體就無法調整高度)
this.Height = txt.Height > lbl.Height ? txt.Height : lbl.Height;
break;
//控件在Text的上邊
case PositionEnum.Up:
lbl.Top = lblPosition.Top;
lbl.Left = lblPosition.Left;
txt.Top = lbl.Bottom;
txt.Left = lblPosition.Left;
lbl.Width = this.Width;
txt.Width = this.Width;
this.Height = txt.Height + lbl.Height;
break;
//label在Text的下方時
case PositionEnum.Down:
txt.Top = lblPosition.Top;
txt.Left = lblPosition.Left;
lbl.Top = txt.Bottom;
lbl.Left = lblPosition.Left;
lbl.Width = this.Width;
txt.Width = this.Width;
this.Height = txt.Height + lbl.Height;
break;
default:
break;
}
}
}
}
其中:
創建枚舉類型屬性的方法:
一、定義一個枚舉,並增加值
二、定義一個此枚舉類型的變量,以用作屬性
三、定義枚舉類型屬性
如上邊例字中的代碼:





































控件中自定事件的方法:
一、定義一個事件委托
二、定義事件委托的方法
注:定義好后,用戶訂閱事件即可。
如上例中代碼:





























