2009-03-31 15 views
8

क्या प्रत्येक संभावित घटना के लिए स्पष्ट रूप से हैंडलर बनाने के बिना विशिष्ट WinForms नियंत्रणों के लिए सभी निकाल दी गई घटनाओं को सूचीबद्ध करने का कोई तरीका है? उदाहरण के लिए, मैं विभिन्न डेटाबेस क्रियाओं के दौरान डेटाग्रिड व्यू और बाध्यकारी स्रोत के बीच आग लगने वाली घटनाओं का अनुक्रम देखना चाहता हूं।घटनाओं को निकालने के लिए नियंत्रण देखें?

उत्तर

8

आप कर सकते थे प्रतिबिंब का उपयोग करें, लेकिन यह विभिन्न घटना हैंडलर हस्ताक्षर शामिल होने के कारण थोड़ा मुश्किल हो जाएगा। मूल रूप से आपको EventInfo प्रकार के प्रत्येक ईवेंट के लिए EventInfo प्राप्त करना होगा, और संपत्ति का उपयोग करने के लिए AddEventHandler पर कॉल करने से पहले किस प्रतिनिधि प्रकार को बनाना है। Delegate.CreateDelegate सामान्य घटना हैंडलर पैटर्न का पालन करने वाली हर चीज के लिए काम करता है ...

यहां एक नमूना ऐप है। ध्यान दें कि यह कोई जांच नहीं कर रहा है - यदि आप इसे "गैर-मानक" ईवेंट के साथ कुछ देते हैं तो यह अपवाद फेंक देगा। आप इवेंट तर्कों को प्रिंट करने के लिए काफी आसानी से प्रतिबिंब का उपयोग कर सकते हैं।

using System; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Reflection; 

namespace ConsoleApp 
{ 
    class Program 
    { 
     [STAThread] 
     static void Main(string[] args) 
     { 
      Form form = new Form { Size = new Size(400, 200) }; 
      Button button = new Button { Text = "Click me" }; 
      form.Controls.Add(button); 
      EventSubscriber.SubscribeAll(button); 
      Application.Run(form); 
     } 
    } 

    class EventSubscriber 
    { 
     private static readonly MethodInfo HandleMethod = 
      typeof(EventSubscriber) 
       .GetMethod("HandleEvent", 
          BindingFlags.Instance | 
          BindingFlags.NonPublic); 

     private readonly EventInfo evt; 

     private EventSubscriber(EventInfo evt) 
     { 
      this.evt = evt; 
     } 

     private void HandleEvent(object sender, EventArgs args) 
     { 
      Console.WriteLine("Event {0} fired", evt.Name); 
     } 

     private void Subscribe(object target) 
     { 
      Delegate handler = Delegate.CreateDelegate(
       evt.EventHandlerType, this, HandleMethod); 
      evt.AddEventHandler(target, handler); 
     } 

     public static void SubscribeAll(object target) 
     { 
      foreach (EventInfo evt in target.GetType().GetEvents()) 
      { 
       EventSubscriber subscriber = new EventSubscriber(evt); 
       subscriber.Subscribe(target); 
      } 
     } 
    } 
} 
+1

बिल्कुल वही जो मैं खोज रहा था! ऐसा लगता है कि मुझे कुछ गंभीर पढ़ने और प्रतिबिंब के साथ tinkering करने की जरूरत है। धन्यवाद! – BikeMrown

+0

वास्तव में बहुत उपयोगी है। धन्यवाद। –

1

मुझे लगता है कि आप ऐसा करने के लिए प्रतिबिंब का उपयोग कर सकते हैं।

0

यह नहीं किया जा सकता है। आप फ्रेमवर्क की कक्षाओं का एक बहुत देखने के लिए परावर्तक का उपयोग करते हैं आप जब घटनाओं फायरिंग एक आम पैटर्न मिल जाएगा:

// fire event 
if (EventDelegate != null) 
    EventDelegate(eventArgs); 

तो घटना भले ही कोई भी इसे की सदस्यता है निकाल दिया नहीं है

+0

मुझे नहीं लगता कि इसका मतलब क्यों नहीं किया जा सकता है - इसका मतलब यह है कि ईवेंट की सदस्यता लेने की आवश्यकता है। उस कोड में प्रत्येक घटना के लिए स्पष्ट रूप से * सदस्यता लेते हुए * और * के बीच एक बड़ा अंतर है। –

+0

मुझे लगता है कि आप बाल बांट रहे हैं। या तो हार्ड कोडित प्रतिनिधियों को बनाकर या प्रतिबिंब का उपयोग करके आप अभी भी 'स्पष्ट रूप से' ईवेंट हैंडलर जोड़ रहे हैं। मेरी प्रतिक्रिया मान ली गई कि वह घटनाओं की सदस्यता लेना नहीं चाहता था (यहां तक ​​कि प्रतिबिंब के माध्यम से) लेकिन कुछ अन्य फैशन में घटनाओं का अनुक्रम देखना चाहता था। –

संबंधित मुद्दे