1. 程式人生 > >DevExpress SpreadsheetControl 反射移除事件委託

DevExpress SpreadsheetControl 反射移除事件委託

c#中,在沒有已繫結的事件委託例項的情況下,移除事件委託。

目前涉及要移除事件包含:CellEndEdit/MouseClick/CellValueChanged/ProtectionWarning/ScrollPositionChanged/SelectionChanged

參照原理程式碼如下:

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button12_Click(object sender, EventArgs e)
        {
            // 為按鈕新增兩個事件
            this.button13.Click += new EventHandler(button12_Click_1);
            this.button13.Click += new EventHandler(button12_Click_2);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button12_Click_1(object sender, EventArgs e)
        {
            MessageBox.Show("1");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button12_Click_2(object sender, EventArgs e)
        {
            MessageBox.Show("2");
        }        

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button14_Click(object sender, EventArgs e)
        {
            // 檢索按鈕的事件,這裡單擊事件的名字是EventClick,要注意的
            Delegate[] invokeList = GetObjectEventList(this.button13, "EventClick");
            if (invokeList != null)
            {
                foreach (Delegate del in invokeList)
                {
                    typeof(Button).GetEvent("Click").RemoveEventHandler(this.button13, del);
                }
            }
        }        

        /// <summary>
        /// 獲取控制元件事件  
        /// </summary>
        /// <param name="p_Control">物件</param>
        /// <param name="p_EventName">事件名 EventClick EventDoubleClick </param>
        /// <returns>委託列</returns>
        public Delegate[] GetObjectEventList(Control p_Control, string p_EventName)
        {
            PropertyInfo _PropertyInfo = p_Control.GetType().GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
            if (_PropertyInfo != null)
            {
                object _EventList = _PropertyInfo.GetValue(p_Control, null);
                if (_EventList != null && _EventList is EventHandlerList)
                {
                    EventHandlerList _List = (EventHandlerList)_EventList;
                    FieldInfo _FieldInfo = (typeof(Control)).GetField(p_EventName, BindingFlags.Static | BindingFlags.NonPublic);
                    if (_FieldInfo == null) return null;
                    Delegate _ObjectDelegate = _List[_FieldInfo.GetValue(p_Control)];
                    if (_ObjectDelegate == null) return null;
                    return _ObjectDelegate.GetInvocationList();
                }
            }
            return null;
        }

但是在DevExpress的SpreadsheetControl控制元件中,通過下面程式碼
(typeof(DevExpress.XtraSpreadsheet.SpreadsheetControl)).GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance)
找不到上面的事件。通過與客服溝通,原來onCellBeginEdit藏在spreadsheetcontrol的InnerControl屬性中,其它幾個事件也是在不同屬性中。

寫了一段程式碼用於查詢事件在哪個屬性中,然後再基於上面的原理程式碼就可以實現在不知道委託例項的情況下移除某事件委託。

            StringBuilder sb = new StringBuilder();
            PropertyInfo[] propertyInfos = spreadsheetControl1.GetType().GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
            List<string> eventNames = new List<string>()
            {
                "onCellBeginEdit",
                "onCellEndEdit",
                "onCellValueChanged",
                "onProtectionWarning",
                "onScrollPositionChanged",
                "onSelectionChanged"
            };
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                object obj = propertyInfo.GetValue(spreadsheetControl1, null);
                if (obj == null) continue;
                foreach (string eventName in eventNames)
                {                    
                    FieldInfo fieldInfo = obj.GetType().GetField(eventName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
                    if (fieldInfo != null)
                        sb.AppendLine(string.Format("事件名稱:{0},屬性名稱:{1}", eventName, propertyInfo.Name));
                }
            }
            memoEdit1.Text = sb.ToString();

附幾個事件對應PropertyInfo名稱

            Dictionary<string, string> events = new Dictionary<string, string>()
            {
                {"onCellBeginEdit","InnerControl"},
                {"onCellEndEdit","InnerControl"},
                {"onCellValueChanged","InnerControl"},
                {"onProtectionWarning","InnerControl"},
                {"onScrollPositionChanged","DocumentModel"},
                {"onSelectionChanged","DocumentModel"}
            };

改寫的GetObjectEventList函式程式碼

        /// <summary>
        /// 獲取SpreadsheetControl中某事件已繫結的委託列表
        /// </summary>
        /// <param name="spreadsheetControl"></param>
        /// <param name="propertyName">擁有該事件的屬性名稱</param>
        /// <param name="eventName">事件名稱,一般字首on</param>
        /// <returns></returns>
        public Delegate[] GetObjectEventList(DevExpress.XtraSpreadsheet.SpreadsheetControl spreadsheetControl, string propertyName, string eventName)
        {
            PropertyInfo propInfo = spreadsheetControl.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic);
            if (propInfo == null) return null;

            object obj = propInfo.GetValue(spreadsheetControl, null);
            if (obj == null) return null;

            FieldInfo fieldInfo = obj.GetType().GetField(eventName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance);
            if (fieldInfo == null) return null;

            Delegate fieldValue = (Delegate)fieldInfo.GetValue(obj);
            if (fieldValue == null) return null;

            Delegate[] delegates = fieldValue.GetInvocationList();
            return delegates;
        }


相關推薦

DevExpress SpreadsheetControl 反射事件委託

c#中,在沒有已繫結的事件委託例項的情況下,移除事件委託。 目前涉及要移除事件包含:CellEndEdit/MouseClick/CellValueChanged/ProtectionWarning/ScrollPositionChanged/SelectionChange

JS綁定事件事件的處理方法

nbsp 觸發 ner 它的 msu eve code ont 一個 addEventListener()與removeEventListener()用於處理指定和刪除事件處理程序操作。全部的DOM節點中都包括這兩種方法,而且它們都接受3個參數:要處理的事件名、作為事件

<jQuery> <方法> 十八. 事件, 觸發事件, 事件對象(阻止冒泡, 阻止跳轉)

value func bsp 方法 function 事件 opp put baidu <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

新增事件事件

第一種: 通過addEventListener新增事件,必須通過removeEventListener移除事件,並且回撥與引數都必須一致,所以如下情況使用匿名回撥函式是無法移除事件的。 不起效: document.addEventListener('mousedown', function() {  

a標籤新增事件及開啟禁用事件

一、新增移除點選事件 <script type="text/javascript" src="jquery.min.js"></script><script type="text/javascript">$(function(){ $(".b").click(f

事件unbind()

unbind([type],[data]) 1、沒有引數,則刪除所有的繫結事件 2、提供事件型別作為引數,則刪除該型別的繫結事件 3、把繫結時傳遞的處理函式作為引數,則刪除該函式  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 T

jQuery鍵盤事件,繫結事件事件,複合事件

鍵盤事件是指每次按下或者釋放鍵盤上得按鍵時所產生的事件,常用的鍵盤事件的方法: keydown()   :按下鍵盤時觸發的事件方法; keyup()   :釋放按鍵時觸發的事件方法; keypress()  :產生可列印的字元時觸發的事件

jquery中有兩種繫結事件事件

今天專案中需要用到這種方法所以記錄一下: /* 1、eventName $("button").click(function(){}) 部分事件不支援 2、on(ecentName,fn) $("button").on('click',function(){}) 所有事件

jQuery on(繫結事件)前別忘了off(事件

廢話不多說直接上程式碼,用到的自己執行看效果<!DOCTYPE html> <html> <head> <title></title> &l

JQuery繫結事件事件、動畫

繫結事件:bind()、on()、live()、delegate()、keyup(); 觸發事件:trigger(‘keyup’)、keyup(); 解綁事件:unbind()、off()、die()、undelegate(); 符合事件:hover()

JS動態新增事件 和 獲取Event (相容IE和Firefox)

今天小弄了一下JS事件,主要說一下FF和IE相容的問題 物件名.addEventListener("事件名(不帶ON)",函式名,true/false);(FF下) 物件名.attachEvent("事件名",函式名);(IE下) 說明:   事件名稱,要注意的是"

js中常用的事件,onclick 單擊事件、onblur 失去焦點事件、onchange改變事件、onmouseover滑鼠進入事件、onmouseout滑鼠事件、onsubmit提交事件

onclick 單擊事件 onblur 失去焦點事件 onchange 當物件或選中區的內容改變時觸發。 onmouseover 當用戶將滑鼠指標移動到物件內時觸發。 onmouseout 當用戶將滑鼠指標移出物件邊界時觸發。 onsubmit 當表單將要被提交時觸發。

js事件監聽:addEventListener() 與 事件:removeEventListener()

說事件繫結得先說事件流 事件流 冒泡型事件流:事件的傳播是從最特定的事件目標到最不特定的事件目標。即從DOM樹的葉子到根。【推薦】 捕獲型事件流:事件的傳播是從最不特定的事件目標到最特定的事件目標。即從DOM樹的根到葉子。 DOM標準採用捕獲+冒泡。兩種事件流都會觸發

JavaScript 中 當用live繫結多個同名事件時,如何事件

先介紹一下我的問題出現的環境: 公司用的dwz框架,需求是在一個頁面點選,載入一個dialog彈出框,每一個頁面都是一個單獨的jsp檔案:其中在彈出的dialog的那個頁面檔案中,有下面一段程式碼: 因為dwz框架的實現機制,就是把當前的程式碼片段載入到主頁面中,所以想給

js新增事件事件、阻止冒泡、阻止瀏覽器預設行為等寫法(相容IE/FF/CHROME)

js新增事件/移除事件/阻止冒泡/阻止瀏覽器預設行為寫法(相容IE/FF/CHROME)1.新增事件var addEvent = function( obj, type, fn ) { if (obj.addEventListener) obj.addEven

jquery的基礎語法、選取元素、操作元素、加事件、掛事件事件

jquery基礎知識 1.jquery檔案的引入,所有的js程式碼要寫在下面那段程式碼下面。 <script src="../jquery-1.11.2.min.js"></script> <!--引入的jquery一定是在最上面的,

新增事件控制代碼和事件控制代碼使用方法

<!DOCTYPE html><html><head><title>新增與移除事件控制代碼</title></head><body><button id="btn">按鈕</

js使用getEventListeners事件監聽器

getEventListeners函式可以用來獲取一個dom元素的事件偵聽器。 如:getEventListneres(wiondow).load 會返回一個偵聽window.load事件的偵聽器陣列。 可以呼叫一個偵聽器的remove方法來移除一個偵聽器。 如 getEv

JQuery中的事件 (六.事件)

1.為同一個元素繫結多個事件 <script type="text/javascript"> $(function(){ $('#btn').bind("click", function(){ $('#test').append("<

錯誤:“ResourceDictionary”根元素需要 x:Class 特性來支持 XAML 文件中的事件處理程序。請 MouseLeftButtonDown 事件事件處理程序.

show prop oid seo forum spa soci main pac 原文:錯誤:“ResourceDictionary”根元素需要 x:Class 特性來支持 XAML 文件中的事件處理程序。請移除 MouseLeftButtonDown 事件的事件處理程序