自定義控件添加事件

事件,委託,總是看起來有點繞,不過本文不介紹這些,只說說如何爲自定義控件添加自定義事件。

本文所說的自定義控件,非繼承其他現有Microsoft控件或者組合控件,而是完全繼承UserControl的東西。

既然不是繼承自其他現有控件或者控件組合,在特定需求下,有添加自定義事件的可能性,或者對繼承自UserControl而得到的事件進行些許擴展,以期以簡便的方式得到更豐富的信息等等。

下面簡單介紹2個例子,有用之人作爲參考,大拿級別的,ignore吧。

例1. 添加完全自定義事件。

需求:

假設客戶端(指添加了自定義控件的窗體等等)想知道用戶是否在控件上按下的Shift鍵(當然,可以通過KeyPress之類的事件來判斷,沒必要再自己整個事件,例子只是個例子),控件作者想通過一個特殊的方式來進行判斷,這就可以選擇自定義事件。

好吧,起個名字,叫Custom,需要客戶端在觸發Custom時得到一個布爾屬性Flag來判斷用戶是否按下Shift。

按部就班:

(1)創建事件

        // 創建事件

        public event CustomEventHandler Custom;

有問題,CustomEventHandler是什麼,當然,這裏需要一個委託,於是還是搞定這個委託

(2)定義委託

    // 定義委託

    public delegate void CustomEventHandler(object sender, CustomEventArgs e);

CustomEventHandler搞定了,又有新問題:CustomEventArgs是啥,其實需要CustomEventArgs來獲得你需要的數據,CustomEventHandler,於是還要定義個CustomEventArgs(這個東西必須繼承自System.EventArgs),在CustomEventArgs裏面定義需要的數據屬性:Flag

(3)定義EventArgs

    // 自定義EventArgs,並添加自定義屬性【Flag】

    public sealed class CustomEventArgs : EventArgs

    {

        private bool testFlag;

        public CustomEventArgs(bool testFlag)

        {

            this.testFlag = testFlag;

        }

        public bool Flag

        {

            get { return testFlag; }

        }

    }

有了CustomEventArgs,以後在觸發事件之後便可以從e.Flag中得到數據。

事件定義完了,這下看看效果先:

能看到在屬性窗口中已經能見到Custom事件

可是Custom到底是怎麼執行和在控件內部觸發的呢,想破頭~

(4)執行事件的代碼

需要一個OnCustom來完成任務

        // 執行事件

        protected virtual void OnCustom(CustomEventArgs e)

        {

            if (Custom != null)

            {

                Custom(this, e);

            }

        }

 

Custom(this, e);

來完成調動客戶端的任務,現在問題的關鍵就在於在合適的地方執行一下OnCustom就可以了,在何處執行,全看你需要的數據在什麼地方能後取得或者發生變化,本例簡單點,就在控件本身的KeyDown事件裏面好了:

(5)何處執行OnCustom

        // 觸發事件處

        private void MyControl_KeyDown(object sender, KeyEventArgs e)

        {

            // 此處省略無關代碼。。。

 

            // 客戶端按下Shift鍵與否

            bool testFlag = e.Shift;

            CustomEventArgs eArgs = new CustomEventArgs(testFlag);

            // 觸發事件

            OnCustom(eArgs);

 

            // 此處省略無關代碼。。。

        }

至此算基本完成,看下最終效果:

在測試窗體上使用自定義控件的Custom事件

 

例2.對原有事件進行一定擴展,並覆蓋原事件

需求:

想在KeyPress中再多獲得一些數據,起個名字:KeyAscii,但是KeyPress中沒有這個,那就自定義一個CustomKeyPress,不用KeyPress,並使其在客戶端隱藏

隱藏的辦法:

        // 屏蔽KeyPress事件使其在客戶端不可見

        [Browsable(false)]

        public new event KeyPressEventHandler KeyPress;

以後跟例一差不多了,

創建事件,委託:

        // 創建事件CustomKeyPress替代KeyPress

        public event CustomKeyPressEventHandler CustomKeyPress;

    // 定義委託

    public delegate void CustomKeyPressEventHandler(object sender, CustomKeyPressEventArgs e);

CustomKeyPressEventArgs要繼承自KeyPressEventArgs,而System.Windows.Forms.KeyPressEventArgs其實繼承自System.EventArgs

   // 自定義KeyPressEventArgs,並添加自定義屬性【KeyAscii】

    public sealed class CustomKeyPressEventArgs : KeyPressEventArgs

    {

        private Int32 keyAscii;

        public CustomKeyPressEventArgs(Int32 keyAscii) : base((char)keyAscii)

        {

            this.keyAscii = keyAscii;

        }

        public Int32 KeyAscii

        {

            get { return keyAscii; }

        }

    }

觸發事件處:

        // 觸發事件處

        protected override void OnKeyPress(KeyPressEventArgs e)

        {

            if (CustomKeyPress != null)

            {

                CustomKeyPressEventArgs eArgs = new CustomKeyPressEventArgs(e.KeyChar);

                CustomKeyPress(this, eArgs);

            }

            base.OnKeyPress(e);

        }

需要特別注意的是,KeyPress被隱藏之後,控件本身的KeyPress事件也將不能被觸發

更新:

關於隱藏事件,其實有別的辦法,

即添加一個Class,繼承ControlDesigner,重寫中的相關方法,然後在控件上面Attribute一下:[DesignerAttribute(typeof(自己添加的Class))]

注意,之前所謂的“在客戶端隱藏”,有點用詞不當,這其實是指在VS IDE的屬性窗口中不可見,並不意味着無法在客戶端訪問,其實使用代碼還是可以的。


文章轉自:http://blog.csdn.net/hugengyong/article/details/5653538

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章