सवाल जब कोई चर का मान बदल जाता है तो ईवेंट को कैसे ट्रिगर करें?


मैं वर्तमान में विजुअल स्टूडियो का उपयोग कर सी # में एक एप्लीकेशन बना रहा हूं। मैं कुछ कोड बनाना चाहता हूं ताकि जब एक चर के पास 1 का मान हो तो कोड का एक निश्चित टुकड़ा किया जाता है। मुझे पता है कि मैं एक कथन का उपयोग कर सकता हूं लेकिन समस्या यह है कि मूल्य एक असीमित प्रक्रिया में बदल दिया जाएगा ताकि तकनीकी रूप से मूल्य बदलने से पहले अगर कथन को अनदेखा किया जा सके।

क्या इवेंट हैंडलर बनाना संभव है ताकि जब परिवर्तनीय मान किसी ईवेंट को बदलता है तो ट्रिगर हो जाता है? यदि हां, तो मैं यह कैसे कर सकता हूं?

यह पूरी तरह से संभव है कि मैं गलत समझा सकता कि कैसे एक कथन कथन काम करता है! कोई भी सहायताकाफी प्रशंसनीय होगी।


76
2018-04-30 14:21


मूल


बस स्पष्ट होने के लिए, एक चर के परिवर्तन को देखते हुए केवल आपके द्वारा किए गए चर के लिए संभव है (या जो पहले से ही IObservable / INotifyPropertyChanged / Event-related है)। यदि आप इसे देखने के लिए डिज़ाइन नहीं किए गए हैं तो आप सिस्टम परिवर्तनीय परिवर्तन का निरीक्षण नहीं कर सकते हैं। - Cœur


जवाब:


मुझे लगता है कि आप एक संपत्ति बनाना चाहते हैं।

public int MyProperty
{
    get { return _myProperty; }
    set
    {
        _myProperty = value;
        if (_myProperty == 1)
        {
            // DO SOMETHING HERE
        }
    }
}

private int _myProperty;

यह किसी भी समय संपत्ति मूल्य में परिवर्तन होने पर आपको कुछ कोड चलाने की अनुमति देता है। यदि आप चाहें तो आप यहां एक इवेंट बढ़ा सकते हैं।


95
2018-04-30 14:25





किसी भी फ़ील्ड का मूल्य बदलने के लिए आप ईवेंट को बढ़ाने के लिए प्रॉपर्टी सेटर का उपयोग कर सकते हैं।

आप अपना खुद का इवेंट हैंडलर प्रतिनिधि हो सकते हैं या आप प्रसिद्ध सिस्टम का उपयोग कर सकते हैं। इवेंटहैंडल प्रतिनिधि।

आमतौर पर इसके लिए एक पैटर्न है:

  1. एक ईवेंट हैंडलर प्रतिनिधि के साथ एक सार्वजनिक कार्यक्रम परिभाषित करें (जिसमें EventArgs टाइप करने का तर्क है)।
  2. OnXXXXX नामक संरक्षित वर्चुअल विधि को परिभाषित करें (उदाहरण के लिए OnMyPropertyValueChanged)। इस विधि में आपको यह जांचना चाहिए कि ईवेंट हैंडलर प्रतिनिधि शून्य है और यदि आप इसे कॉल नहीं कर सकते हैं (इसका मतलब है कि ईवेंट प्रतिनिधिमंडल से एक या अधिक तरीके संलग्न हैं)।
  3. जब भी आप ग्राहकों को सूचित करना चाहते हैं कि कुछ बदल गया है, तो इस संरक्षित विधि को कॉल करें।

यहां एक उदाहरण दिया गया है

private int _age;

//#1
public event System.EventHandler AgeChanged;

//#2
protected virtual void OnAgeChanged()
{ 
     if (AgeChanged != null) AgeChanged(this,EventArgs.Empty); 
}

public int Age
{
    get
    {
         return _age;
    }

    set
    {
         //#3
         _age=value;
         OnAgeChanged();
    }
 }

इस दृष्टिकोण का लाभ यह है कि यदि आवश्यक हो तो व्यवहार को बदलने के लिए आप किसी भी अन्य वर्ग को अपनी कक्षा से उत्तराधिकारी बनाना चाहते हैं।

यदि आप एक अलग थ्रेड में एक घटना को पकड़ना चाहते हैं जिसे उठाया जा रहा है तो आपको सावधान रहना चाहिए कि किसी अन्य थ्रेड में परिभाषित वस्तुओं की स्थिति को न बदलना जो क्रॉस थ्रेड अपवाद को फेंकने का कारण बनता है। इससे बचने के लिए आप या तो ऑब्जेक्ट पर एक Invoke विधि का उपयोग कर सकते हैं, जिसे आप यह सुनिश्चित करने के लिए अपने राज्य को बदलना चाहते हैं कि ईवेंट को उठाए गए उसी थ्रेड में परिवर्तन हो रहा है या यदि आप Windows फॉर्म से निपट रहे हैं एक समानांतर धागे में चीजों को अच्छा और आसान करने के लिए बैकगॉरंडवर्कर का उपयोग कर सकते हैं।


47
2018-04-30 15:00



पूरे वेब पर सबसे अच्छी व्याख्याओं में से एक। मुझे लगता है कि मैं अंत में कस्टम इवेंट हैंडलिंग समझ रहा हूं। इस पोस्ट के लिए धन्यवाद। - Ricardo Garcia


.NET Framework वास्तव में एक इंटरफ़ेस प्रदान करता है जिसका उपयोग आप संपत्ति को बदलते समय ग्राहकों को सूचित करने के लिए कर सकते हैं: System.ComponentModel.INotifyPropertyChanged। इस इंटरफेस में एक घटना संपत्ति है। इसका आमतौर पर बाध्यकारी के लिए डब्ल्यूपीएफ में उपयोग किया जाता है लेकिन मुझे संपत्ति परिवर्तन अधिसूचना को मानकीकृत करने के तरीके के रूप में व्यवसाय परतों में यह उपयोगी पाया गया है।

थ्रेड सुरक्षा के मामले में मैं सेटर में एक ताला लगा दूंगा ताकि आप किसी भी दौड़ की स्थिति में भाग न सकें।

कोड में मेरे विचार यहां दिए गए हैं :):

public class MyClass : INotifyPropertyChanged
{
    private object _lock;

    public int MyProperty
    {
        get
        {
            return _myProperty;
        }
        set
        {
            lock(_lock)
            {
                //The property changed event will get fired whenever
                //the value changes. The subscriber will do work if the value is
                //1. This way you can keep your business logic outside of the setter
                if(value != _myProperty)
                {
                    _myProperty = value;
                    NotifyPropertyChanged("MyProperty");
                }
            }
        }
    }

    private NotifyPropertyChanged(string propertyName)
    {
        //Raise PropertyChanged event
    }
    public event PropertyChangedEventHandler PropertyChanged;
}


public class MySubscriber
{
    private MyClass _myClass;        

    void PropertyChangedInMyClass(object sender, PropertyChangedEventArgs e)
    {
        switch(e.PropertyName)
        {
            case "MyProperty":
                DoWorkOnMyProperty(_myClass.MyProperty);
                break;
        }
    }

    void DoWorkOnMyProperty(int newValue)
    {
        if(newValue == 1)
        {
             //DO WORK HERE
        }
    }
}

उम्मीद है कि यह सहायक है :)


35
2018-04-30 21:13



लॉक को शामिल करने के लिए +1 जो अन्य उत्तरों को छोड़ दें। - ctacke
ऑब्जेक्ट _lock का उपयोग क्या है? - Lode Vlaeminck
@LodeVlaeminck यह संसाधित होने के दौरान संपत्ति के मूल्य को बदलने से रोकता है। - David Suarez


बस एक संपत्ति का उपयोग करें

int  _theVariable;
public int TheVariable{
  get{return _theVariable;}
  set{
    _theVariable = value; 
    if ( _theVariable == 1){
      //Do stuff here.
    }
  }
}

8
2018-04-30 14:28