简体   繁体   English

当变量的值改变时如何触发事件?

[英]How to trigger event when a variable's value is changed?

I'm currently creating an application in C# using Visual Studio.我目前正在使用 Visual Studio 在 C# 中创建一个应用程序。 I want to create some code so that when a variable has a value of 1 then a certain piece of code is carried out.我想创建一些代码,以便当变量的值为 1 时执行某段代码。 I know that I can use an if statement but the problem is that the value will be changed in an asynchronous process so technically the if statement could be ignored before the value has changed.我知道我可以使用 if 语句,但问题是该值将在异步过程中更改,因此从技术上讲,可以在值更改之前忽略 if 语句。

Is it possible to create an event handler so that when the variable value changes an event is triggered?是否可以创建一个事件处理程序,以便在变量值更改时触发事件? If so, how can I do this?如果是这样,我该怎么做?

It is completely possible that I could have misunderstood how an if statement works.我完全有可能误解了 if 语句的工作原理。 Any help would be much appreciated.任何帮助将非常感激。

Seems to me like you want to create a property.在我看来,你想创建一个属性。

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

private int _myProperty;

This allows you to run some code any time the property value changes.这允许您在属性值更改时运行一些代码。 You could raise an event here, if you wanted.如果你愿意,你可以在这里发起一个活动。

You can use a property setter to raise an event whenever the value of a field is going to change.每当字段的值发生变化时,您都可以使用属性设置器引发事件。

You can have your own EventHandler delegate or you can use the famous System.EventHandler delegate.您可以拥有自己的 EventHandler 委托,也可以使用著名的 System.EventHandler 委托。

Usually there's a pattern for this:通常有一个模式:

  1. Define a public event with an event handler delegate (that has an argument of type EventArgs).使用事件处理程序委托(具有 EventArgs 类型的参数)定义公共事件。
  2. Define a protected virtual method called OnXXXXX (OnMyPropertyValueChanged for example).定义一个名为 OnXXXXX 的受保护虚拟方法(例如 OnMyPropertyValueChanged)。 In this method you should check if the event handler delegate is null and if not you can call it (it means that there are one or more methods attached to the event delegation).在此方法中,您应该检查事件处理程序委托是否为 null,如果不是,您可以调用它(这意味着事件委托附加了一个或多个方法)。
  3. Call this protected method whenever you want to notify subscribers that something has changed.每当您想通知订阅者某些事情发生了变化时,请调用此受保护的方法。

Here's an example这是一个例子

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();
    }
 }

The advantage of this approach is that you let any other classes that want to inherit from your class to change the behavior if necessary.这种方法的优点是您可以让任何其他想要从 class 继承的类在必要时更改行为。

If you want to catch an event in a different thread that it's being raised you must be careful not to change the state of objects that are defined in another thread which will cause a cross thread exception to be thrown.如果您想在另一个线程中捕获一个正在引发的事件,您必须小心不要更改在另一个线程中定义的对象的 state,这将导致引发跨线程异常。 To avoid this you can either use an Invoke method on the object that you want to change its state to make sure that the change is happening in the same thread that the event has been raised or in case that you are dealing with a Windows Form you can use a BackgourndWorker to do things in a parallel thread nice and easy.为避免这种情况,您可以在要更改其 state 的 object 上使用 Invoke 方法,以确保更改发生在引发事件的同一线程中,或者如果您正在处理 ZAEA23489CE3AA9B6406EBB2可以使用 BackgourndWorker 在并行线程中轻松轻松地做事。

The .NET framework actually provides an interface that you can use for notifying subscribers when a property has changed: System.ComponentModel.INotifyPropertyChanged. .NET 框架实际上提供了一个接口,您可以使用该接口在属性发生更改时通知订阅者:System.ComponentModel.INotifyPropertyChanged。 This interface has one event PropertyChanged.此接口有一个事件 PropertyChanged。 Its usually used in WPF for binding but I have found it useful in business layers as a way to standardize property change notification.它通常在 WPF 中用于绑定,但我发现它在业务层中作为一种标准化属性更改通知的方式很有用。

In terms of thread safety I would put a lock under in the setter so that you don't run into any race conditions.在线程安全方面,我会在设置器中加一个锁,这样你就不会遇到任何竞争条件。

Here are my thoughts in code:):这是我在代码中的想法:):

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
        }
    }
}

Hope this is helpful:)希望这会有所帮助:)

just use a property只使用一个属性

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

you can use generic class:您可以使用通用 class:

class Wrapped<T>  {
    private T _value;

    public Action ValueChanged;

    public T Value
    {
        get => _value;

        set
        {
            if ( _value != value )
            {
                _value = value;
                OnValueChanged();
            }
        }
    }

    protected virtual void OnValueChanged() => ValueChanged?.Invoke() ;
}

and will be able to do the following:并将能够执行以下操作:

var i = new Wrapped<int>();

i.ValueChanged += () => { Console.WriteLine("changed!"); };

i.Value = 10;
i.Value = 10;
i.Value = 10;
i.Value = 10;

Console.ReadKey();

result:结果:

changed!
changed!
changed!
changed!
changed!
changed!
changed!

A simple method involves using the get and set functions on the variable一个简单的方法是对变量使用 get 和 set 函数


    using System;
    public string Name{
    get{
     return name;
    }
    
    set{
     name= value;
     OnVarChange?.Invoke();
    }
    }
    private string name;
    
    public event System.Action OnVarChange;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 更改static int变量时的触发事件? - Trigger event when static int variable is changed? 如何在变量在指定时间范围内获得相同值时触发事件? - How to trigger an event when a variable gets the same value in a specified timeframe? 任何TextBox的文本发生更改时触发事件处理程序 - Trigger Event Handler when any TextBox's text has changed 变量值更改时触发事件 - Trigger an Event when a Variable Value Changes 更改变量值时调用函数的最佳方法? - Best way to call a function in the event of a variable's value is changed? C#如何在更改静态Arraylist计数时触发事件? - C# How to trigger an event when a static Arraylist count is changed? 当CheckListBox中的任何CheckState值更改时如何触发事件 - How to trigger an event when any of CheckState values in CheckListBox is changed 如何将变量的值存储在列表中,并且在更改变量时不更改它的值? - How to store a variable's value in a list and not have it changed when that variable is altered? WebBrowser文本选择更改时的触发事件 - Trigger event when WebBrowser text selection changed 组合框值更改时如何触发按钮 - How to trigger a button when combo box value changed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM