控件属性动作
控件應(yīng)該定義屬性而不是公共字段,因?yàn)榭梢暬O(shè)計(jì)器在屬性瀏覽器中顯示屬性,而不顯示字段。屬性就像智能字段。屬性通常具有帶訪問函數(shù)的專用數(shù)據(jù)成員,在語法上屬性被作為類的字段進(jìn)行訪問。(雖然屬性可以具有不同的訪問級(jí)別,但此處的討論將重點(diǎn)放在公共訪問這種更加常見的情況上。
?
屬性定義通常由以下兩部分組成:
?
1、專用數(shù)據(jù)成員的定義。
[c-sharp] view plaincopyprint?private int number = 0;
?
2、使用屬性聲明語法對(duì)公共屬性進(jìn)行的定義。
[c-sharp] view plaincopyprint?//該語法通過 get 和 set 訪問函數(shù)將專用數(shù)據(jù)成員和公共屬性關(guān)聯(lián)起來。 public int MyNumber { get { return number; } set { number = value; } }
?
?
雖然屬性定義中通常包含專用數(shù)據(jù)成員,但這不是必需的。get 訪問器不用訪問私有數(shù)據(jù)成員就可以返回值。get 方法返回系統(tǒng)時(shí)間的屬性就屬于這種情況。屬性啟用數(shù)據(jù)隱藏,訪問器方法隱藏屬性的實(shí)現(xiàn)。
?
定義屬性時(shí)需考慮以下重要的注意事項(xiàng):
?
1、?? 必須將屬性應(yīng)用于定義的屬性。屬性用來指定設(shè)計(jì)器顯示屬性的方式。
2、?? 如果改變屬性將影響控件的外觀顯示,請(qǐng)從 set 訪問器中調(diào)用 Invalidate 方法(從 Control 繼承該方法)。Invalidate 隨后調(diào)用 OnPaint 方法,該方法將重新繪制控件。為提高效率起見,對(duì) Invalidate 的多次調(diào)用將產(chǎn)生對(duì) OnPaint 的一次調(diào)用。
3、?? .NET Framework 類庫為常見數(shù)據(jù)類型(如整數(shù)、小數(shù)、布爾值和其他數(shù)據(jù))提供了類型轉(zhuǎn)換器。類型轉(zhuǎn)換器的目的通常是用來提供字符串到數(shù)值的轉(zhuǎn)換(從字符串?dāng)?shù)據(jù)轉(zhuǎn)換為其他數(shù)據(jù)類型)。常見數(shù)據(jù)類型與默認(rèn)類型轉(zhuǎn)換器(將數(shù)值轉(zhuǎn)換為字符串,并將字符串轉(zhuǎn)換為相應(yīng)數(shù)據(jù)類型)相關(guān)聯(lián)。如果定義了自定義(即,非標(biāo)準(zhǔn))數(shù)據(jù)類型的屬性,則應(yīng)用的屬性必須將類型轉(zhuǎn)換器指定為與該屬性相關(guān)聯(lián)。還可以使用屬性使自定義 UI 類型編輯器與某個(gè)屬性相關(guān)聯(lián)。UI 類型編輯器提供了一個(gè)用來編輯屬性或數(shù)據(jù)類型的用戶界面。顏色選擇器是 UI 類型編輯器的一個(gè)示例。
?
例:首先創(chuàng)建一個(gè)名為 DrawingMode 的簡單枚舉。
[c-sharp] view plaincopyprint?public enum DrawingMode { Happy = 0, Sad = 1, Angry = 2 }
?
接著,向該控件添加 MyDrawingMode 屬性
[c-sharp] view plaincopyprint?private DrawingMode myDrawingMode; [Browsable(true), Category("Appearance")] public DrawingMode MyDrawingMode { get { return myDrawingMode; } set { myDrawingMode = value; SetColors(); } }
?
對(duì) SetColors 方法的調(diào)用只是根據(jù) myDrawingMode 的值設(shè)置控件的 BackColor 和 ForeColor。向控件添加下面的代碼。
[c-sharp] view plaincopyprint?private void SetColors() { switch (myDrawingMode) { case DrawingMode.Happy: this.BackColor = Color.Yellow; this.ForeColor = Color.Green; break; case DrawingMode.Sad: this.BackColor = Color.LightSlateGray; this.ForeColor = Color.White; break; case DrawingMode.Angry: this.BackColor = Color.Red; this.ForeColor = Color.Teal; break; default: this.BackColor = Color.Black; this.ForeColor = Color.White; break; } }
?
現(xiàn)在可以向控件的paint方法添加代碼,來繪制控件的樣式,也可以添加現(xiàn)有的控件來組合實(shí)現(xiàn)想要的功能(例子里面有)。
[c-sharp] view plaincopyprint?private void UserControl1_Paint(object sender, PaintEventArgs e) { Graphics curG = e.Graphics; Pen curPen = new Pen(Color.Black); Rectangle curRect = new Rectangle(0, 0, Width - 2, Height - 3); curG.DrawRectangle(curPen, curRect); curG.DrawEllipse(curPen, curRect); }
?
?
?
?
?
?
事件(Event)
事件是對(duì)象發(fā)送的消息,以發(fā)信號(hào)通知操作的發(fā)生。操作可能是由用戶交互(例如鼠標(biāo)單擊)引起的,也可能是由某些其他的程序邏輯觸發(fā)的。引發(fā)事件的對(duì)象稱為事件發(fā)送方。捕獲事件并對(duì)其作出響應(yīng)的對(duì)象叫做事件接收方。
在事件通信中,事件發(fā)送方類不知道哪個(gè)對(duì)象或方法將接收到(處理)它引發(fā)的事件。所需要的是在源和接收方之間存在一個(gè)媒介(或類似指針的機(jī)制)。.NET Framework 定義了一個(gè)特殊的類型(Delegate),該類型提供函數(shù)指針的功能。
?
代理(delegate)
?
?
?
?
?
?
?
?
?
delegate是C#中的一種類型,它實(shí)際上是一個(gè)能夠持有對(duì)某個(gè)方法的引用的類。與其它的類不同,delegate類能夠擁有一個(gè)簽名(signature),并且它只能持有與它的簽名相匹配的方法的引用。這樣,代理就等效于一個(gè)類型安全函數(shù)指針或一個(gè)回調(diào)。它允許你傳遞一個(gè)類A的方法m給另一個(gè)類B的對(duì)象,使得類B的對(duì)象能夠調(diào)用這個(gè)方法m。但與函數(shù)指針相比,delegate有許多函數(shù)指針不具備的優(yōu)點(diǎn)。首先,函數(shù)指針只能指向靜態(tài)函數(shù),而delegate既可以引用靜態(tài)函數(shù),又可以引用非靜態(tài)成員函數(shù)。在引用非靜態(tài)成員函數(shù)時(shí),delegate不但保存了對(duì)此函數(shù)入口指針的引用,而且還保存了調(diào)用此函數(shù)的類實(shí)例的引用。其次,與函數(shù)指針相比,delegate是面向?qū)ο蟆㈩愋桶踩⒖煽康氖芸?#xff08;managed)對(duì)象。也就是說,runtime能夠保證delegate指向一個(gè)有效的方法,你無須擔(dān)心delegate會(huì)指向無效地址或者越界地址。
?
實(shí)現(xiàn)一個(gè)delegate是很簡單的,通過以下3個(gè)步驟即可實(shí)現(xiàn)一個(gè)delegate:
?
1. 聲明一個(gè)delegate對(duì)象,它應(yīng)當(dāng)與你想要傳遞的方法具有相同的參數(shù)和返回值類型。
2. 創(chuàng)建delegate對(duì)象,并將你想要傳遞的函數(shù)作為參數(shù)傳入。
3. 在要實(shí)現(xiàn)異步調(diào)用的地方,通過上一步創(chuàng)建的對(duì)象來調(diào)用方法。
[c-sharp] view plaincopyprint?public class MyDelegateTest { // 步驟1,聲明delegate對(duì)象 public delegate void MyDelegate(string name); // 這是我們欲傳遞的方法,它與MyDelegate具有相同的參數(shù)和返回值類型 public static void MyDelegateFunc(string name) { Console.WriteLine("Hello, {0}", name); } public static void Main () { // 步驟2,創(chuàng)建delegate對(duì)象 MyDelegate md = new MyDelegate(MyDelegateTest.MyDelegateFunc); // 步驟3,調(diào)用delegate md("sam1111"); } }
?
?
C#中的事件處理實(shí)際上是一種具有特殊簽名的delegate,象下面這個(gè)樣子:
[c-sharp] view plaincopyprint?public delegate void MyEventHandler(object sender, MyEventArgs e);
?
其中的兩個(gè)參數(shù),sender代表事件發(fā)送者,e是事件參數(shù)類。MyEventArgs類用來包含與事件相關(guān)的數(shù)據(jù),所有的事件參數(shù)類都必須從System.EventArgs類派生。當(dāng)然,如果你的事件不含特別的參數(shù),那么可以直接用System.EventArgs類作為參數(shù)。
結(jié)合delegate的實(shí)現(xiàn),我們可以將自定義事件的實(shí)現(xiàn)歸結(jié)為以下幾步:
?
1:定義delegate對(duì)象類型,它有兩個(gè)參數(shù),第一個(gè)參數(shù)是事件發(fā)送者對(duì)象,第二個(gè)參數(shù)是事件參數(shù)類對(duì)象。
2:定義事件參數(shù)類,此類應(yīng)當(dāng)從System.EventArgs類派生。如果事件不帶參數(shù),這一步可以省略。
3:定義事件處理方法,它應(yīng)當(dāng)與delegate對(duì)象具有相同的參數(shù)和返回值類型。
4:用event關(guān)鍵字定義事件對(duì)象,它同時(shí)也是一個(gè)delegate對(duì)象。
5:用+=操作符添加事件到事件隊(duì)列中(-=操作符能夠?qū)⑹录年?duì)列中刪除)。
6:在需要觸發(fā)事件的地方用調(diào)用delegate的方式寫事件觸發(fā)方法。一般來說,此方法應(yīng)為protected訪問限制,既不能以public方式調(diào)用,但可以被子類繼承。名字是可以是OnEventName。
7:在適當(dāng)?shù)牡胤秸{(diào)用事件觸發(fā)方法觸發(fā)事件。
?
下面是一個(gè)例子,例子模仿容器和控件的模式,由控件觸發(fā)一個(gè)事件,在容器中捕捉并且進(jìn)行處理。
[c-sharp] view plaincopyprint?/// <summary> /// 事件的觸發(fā)者 /// </summary> public class Control { public delegate void SomeHandler(object sender, System.EventArgs e); public event SomeHandler SomeEvent; public Control() { //這里使用的delegate必須與事件中聲名的一致 this.SomeEvent += new SomeHandler(this.ProcessSomeEvent); } public void RaiseSomeEvent() { EventArgs e = new EventArgs(); Console.Write("Please input 'a':"); string s = Console.ReadLine(); //在用戶輸入一個(gè)小a的情況下觸發(fā)事件,否則不觸發(fā) if (s == "a") { SomeEvent(this, e); } } //事件的觸發(fā)者自己對(duì)事件進(jìn)行處理,這個(gè)方法的參數(shù)必須和代理中聲名的一致 private void ProcessSomeEvent(object sender, EventArgs e) { Console.WriteLine("hello"); } }
?
?
[c-sharp] view plaincopyprint?/// <summary> /// 事件的接收和處理者 /// </summary> class Container { private Control ctrl = new Control(); public Container() { //這里使用的delegate必須與事件中聲名的一致 ctrl.SomeEvent += new Control.SomeHandler(this.ResponseSomeEvent); ctrl.RaiseSomeEvent(); } public static void Main() { Container pane = new Container(); Console.ReadLine(); } //這是事件的接受者對(duì)事件的響應(yīng) private void ResponseSomeEvent(object sender, EventArgs e) { Console.WriteLine("Some event occur!"); } }
?
?
[c-sharp] view plaincopyprint?//程序運(yùn)行的結(jié)果如下: please input 'a':a hello Some event occur!
?
?
?
?
?
而我們看到的工具箱上的每個(gè)控件都有自己的圖標(biāo),我們可以通過下面語句為自己制作的控件添加圖標(biāo)。
[c-sharp] view plaincopyprint?[ToolboxBitmap(@"D:/Program Files/qq/AirDLIcon/1381love.ico")] public partial class UserControl1 : UserControl {………….}
?
即在控件類前面加上ToolboxBitmap屬性,屬性參數(shù)指向一個(gè)圖片的地址就可以了。
?
再比如,我自己定義了一個(gè)屬性,如果不進(jìn)行設(shè)置,是不會(huì)在屬性窗口顯示的,也就是我們?cè)谟每丶臅r(shí)候不能夠通過可視化的界面對(duì)其進(jìn)行設(shè)置,想讓它在屬性窗口顯示,就要用Browsable屬性了,如下面的例子。
[c-sharp] view plaincopyprint?public enum DrawingMode{Happy = 0,Sad = 1,Angry = 2} private DrawingMode myDrawingMode; [Browsable(true)] public DrawingMode MyDrawingMode { get { return myDrawingMode; } set { myDrawingMode = value; } }
?
?
像這樣的屬性還可以組合使用,例如上面的例子,我在Browsable屬性后面再加上一個(gè)Category屬性,讓它的參數(shù)等于Appearance,這時(shí)我們自己定義的屬性就從屬性框中的雜項(xiàng)轉(zhuǎn)到了外觀項(xiàng)里面了。
[c-sharp] view plaincopyprint?[Browsable(true), Category("Appearance")]
?
像這樣的屬性有很多,我主要羅列下面這些,在使用的時(shí)候大家可以參照。
?
Browsable
適用于屬性和事件,指定屬性或事件是否應(yīng)該顯示在屬性瀏覽器中。
Category
適用于屬性和事件,指定類別的名稱,在該類別中將對(duì)屬性或事件進(jìn)行分組。當(dāng)使用了類別時(shí),組件屬性和事件可以按邏輯分組顯示在屬性瀏覽器中。
Description
適用于屬性和事件,定義一小塊文本,該文本將在用戶選擇屬性或事件時(shí)顯示在屬性瀏覽器底部。
Bindable
適用于屬性 指定是否要綁定到該屬性。
DefaultProperty
適用于屬性,(將此特性插入類聲明前。)指定組件的默認(rèn)屬性。當(dāng)用戶單擊控件時(shí),將在屬性瀏覽器中選定該屬性。
DefaultValue
適用于屬性,為屬性設(shè)置一個(gè)簡單的默認(rèn)值。
Editor
適用于屬性,指定在可視設(shè)計(jì)器中編輯(更改)屬性時(shí)要使用的編輯器。
Localizable
適用于屬性,指定屬性可本地化。當(dāng)用戶要本地化某個(gè)窗體時(shí),任何具有該特性的屬性都將自動(dòng)永久駐留到資源文件中。
DesignerSerializationVisibility
適用于屬性,指定顯示在屬性瀏覽器中的屬性是否應(yīng)該(以及如何)永久駐留在代碼中。
TypeConverter
適用于屬性,指定將屬性的類型轉(zhuǎn)換為另一個(gè)數(shù)據(jù)類型時(shí)要使用的類型轉(zhuǎn)換器。
DefaultEvent
適用于事件,(將此特性插入類聲明前。)指定組件的默認(rèn)事件。這是當(dāng)用戶單擊組件時(shí)在屬性瀏覽器中選定的事件。
?
轉(zhuǎn)至http://blog.csdn.net/a237428367/article/details/5926445
轉(zhuǎn)載于:https://www.cnblogs.com/q280352958/archive/2013/02/26/2933099.html
總結(jié)
- 上一篇: 大漠插件最新版7.2107
- 下一篇: C语言递归练习