2010-11-18 9 views
50

मान लें, मैं इवेंट हैंडलर निर्दिष्ट करते समय कुछ अतिरिक्त डेटा पास करना चाहता हूं। निम्नलिखित कोड पर विचार करें:सी # एक घटना हैंडलर के लिए अतिरिक्त पैरामीटर गुजर रहा है?

private void setup(string someData) 
{ 
    Object.assignHandler(evHandler); 
} 

public void evHandler(Object sender) 
{ 
    // need someData here!!! 
} 

मैं अपने evHandler विधि में कुछ डेटा प्राप्त करने के बारे में कैसे जाउंगा?

+0

मैं इस सवाल में एक अधिक मानक समाधान, पहले उत्तर http://stackoverflow.com/questions/14058412/passing-parameter-to-an-event-handler/14058441#14058441 –

उत्तर

49
private void setup(string someData) 
{ 
    Object.assignHandler((sender) => evHandler(sender,someData)); 
} 
public void evHandler(Object sender, string someData) 
{ 
    // need someData here!!! 
} 
+1

यह एक अच्छा समाधान है, लेकिन अगर इवेंट हैंडलर में पहले से ही TArgs है। जैसे + = नया इवेंट हैंडलर (evHandler)? – Roast

+0

हाय @ लिली, यह पूरी तरह स्पष्ट नहीं है कि आप क्या पूछ रहे हैं। कुछ और विवरण के साथ एक प्रश्न (टिप्पणी के बजाए) पोस्ट करना बेहतर हो सकता है और कुछ कोड यह दिखाने के लिए कि आप क्या करने की कोशिश कर रहे हैं। – spender

+1

धन्यवाद, इसने मुझे एक समस्या हल कर दी, लेकिन मैं सी # के लिए नया हूं, तो क्या आप यह समझाने में दिमाग करेंगे कि यह भाषा क्या है या मुझे स्पष्टीकरण के लिए Google को एक कीवर्ड दे रहा है? –

0

ठीक है, सरल विधि आईडी someData बनाने के लिए तो जैसे एक सदस्य चर:

public class MyClass 
{ 
    private string _eventData; 

    private void setup(string someData) 
    { 
     _eventData = someData; 
     Object.assignHandler(evHandler); 
    } 

    public void evHandler() 
    { 
     // do something with _eventData here 
    } 
} 

मुझे यकीन है कि सबसे अच्छा जिस तरह से यह करना है नहीं कर रहा हूँ, लेकिन यह वास्तव में घटना प्रकार पर निर्भर करता, वस्तु, आदि

+1

इस बारे में सोच रहा था है विधि, हालांकि अलग-अलग कुछ डेटा के साथ सेटअप कई बार कहा जा सकता है। वह डेटा प्रत्येक हैंडलर के लिए अद्वितीय होना चाहिए। –

+0

उस मामले में, स्पेंडर या मार्क का समाधान बहुत बेहतर है – CodingGorilla

17

कब्जा कर लिया चर:

private void setup(string someData) 
{ 
    Object.assignHandler((sender,args) => { 
     evHandler(sender, someData); 
    }); 
} 

public void evHandler(Object sender, string someData) 
{ 
    // use someData here 
} 

या (सी # 2.0 वैकल्पिक):

Object.assignHandler((EventHandler)delegate(object sender,EventArgs args) { 
     evHandler(sender, someData); 
    }); 
+2

कैप्चर चर === बंद हो गया है? – Matt

+2

@ मैट - हाँ, कैप्चर वैरिएबल लेक्सिकल क्लोजर हैं। –

+0

स्पष्टीकरण के लिए, पहला समाधान सी # .NET 2.0 के लिए मान्य नहीं है? –

2

यदि आप ऐसा करने की कोशिश कर सकते हैं:

string yourObject; 

theClassWithTheEvent.myEvent += (sender, model) => 
{ 
yourObject = "somthing"; 
} 
0

आप वस्तु के आधार पर अतिरिक्त गुण एक कस्टम वस्तु बना सकते हैं:

class CustomObject : Object 
{ 
    public string SomeData; 
} 

private void setup(string someData) 
{ 
    CustomObject customObject = new CustomObject { SomeData = someData }; 
    CustomObject.assignHandler(evHandler); 
} 

public void evHandler(Object sender) 
{ 
    string someData = ((CustomObject)sender).SomeData; 
} 

डेटा अब बदला नहीं जाना चाहिए, तो प्रारंभ करने के बाद, आप एक कस्टम कन्स्ट्रक्टर भी जोड़ सकते हैं, उदाहरण के लिए।

14

मुझे उपरोक्त @ स्पेंडर के उदाहरण को विशेष रूप से: Object.assignHandler((sender) => evHandler(sender,someData)); के साथ पता लगाने में कठिन समय था क्योंकि शाब्दिक अर्थ में Object.assignHandler जैसी कोई चीज़ नहीं है। तो मैंने थोड़ी अधिक गुगलिंग की और this example पाया।

स्निप

सामान्य दृष्टिकोण एक ईवेंट हैंडलर अपने संशोधित है कि के साथ एक अनाम विधि का उपयोग करने के लिए है: पीटर Duniho द्वारा जवाब एक ही है कि मेरे सिर में क्लिक किया है (यह मेरा काम नहीं है) था हस्ताक्षर। उदाहरण के लिए:

void Onbutton_click(object sender, EventArgs e, int i) { ... } 

button.Click += delegate(object sender, EventArgs e) 
{ Onbutton_click(sender, e, 172); }; 

बेशक, आप 172 में गुजरती हैं, या तीसरे पैरामीटर किसी पूर्णांक बनाने के लिए नहीं है। :)

/

कटाव कि उदाहरण मैं एक Timer.Elapsed घटना का उपयोग कर लैम्ब्डा अंकन करने के लिए ComboBoxItem वस्तुओं दो कस्टम में पारित करने में सक्षम था का उपयोग करना:

simulatorTimer.Elapsed += 
(sender, e) => onTimedEvent(sender, e, 
(ComboBoxItem) cbPressureSetting.SelectedItem, 
(ComboBoxItem) cbTemperatureSetting.SelectedItem); 

और फिर इसे का हैंडलर में:

static void onTimedEvent(object sender, EventArgs e, ComboBoxItem pressure, ComboBoxItem temperature) 
    { 
     Console.WriteLine("Requested pressure: {0} PSIA\nRequested temperature: {1}° C", pressure, temperature); 
    } 

यह ऊपर दिए गए उदाहरणों से कोई नया कोड नहीं है, लेकिन यह एच प्रदर्शित करता है उन्हें समझने के लिए ओउ। उम्मीद है कि मेरे जैसे किसी को यह निर्देशक & उपयोगी लगता है, इसलिए वे इस तरह की अवधारणा को समझने की कोशिश करने में घंटों खर्च नहीं करते हैं।

यह कोड मेरे प्रोजेक्ट में काम करता है (ComboBoxItem ऑब्जेक्ट्स के साथ गैर-थ्रेड-सुरक्षित अपवाद को छोड़कर, जो कि मुझे विश्वास नहीं है कि उदाहरण कैसे काम करता है)। मैं अब यह पता लगा रहा हूँ।

0

यहां मेरा एक-लाइन समाधान है जो टाइमर हैंडलर को अतिरिक्त पैरामीटर पास करता है।

private void OnFailed(uint errorCode, string message) 
{ 
    ThreadPoolTimer.CreateTimer((timer) => { 
    UI.ErrorMessage = string.Format("Error: 0x{0:X} {1}", errorCode, message); 
    }, System.TimeSpan.FromMilliseconds(100)); 
} 
0

मेरा प्रश्न है कि समान था चिह्नित किया गया था एक नकली तो सोचा था कि मैं यहाँ एक जवाब जोड़ना होगा, क्योंकि यह मुझे मेरे सवाल पर नहीं दूँगा।

class Program 
    { 
     delegate void ComponentEventHandler(params dynamic[] args); 

     event ComponentEventHandler onTest; 

     static void Main(string[] args) 
     { 
      Program prg = new Program(); 

      // can be bound to event and called that way 
      prg.onTest += prg.Test; 
      prg.onTest.Invoke("What", 5, 12.0); 

      Console.ReadKey(); 
     } 

     public void Test(params dynamic[] values) 
     { 
      // assign our params to variables 
      string name = values[0]; 
      int age = values[1]; 
      double value = values[2]; 

      Console.WriteLine(name); 
      Console.WriteLine(age); 
      Console.WriteLine(value); 
     } 
    } 
संबंधित मुद्दे