Aloha
Aloha

Reputation: 914

Is there an event that will raise when a variable has changed?

I know that the proper course of action is to create a class, make an event in said class, then use said class in another part of the program where the variable would be changed (e.g. Use said class in the equal button of a calculator, so that an event handler knows that a variable has been changed because an event would be fired). But, trying to streamline my code, I'm looking for a way to monitor a variable directly without an infinite loop/timer and raise an event when it changes. Is there such a thing? If not, are there any other alternatives aside for the one I mentioned?

Here is what I'm trying to mention:

Code that changes a variable -> Another piece of code (not a loop) watching for changes then throws an event if there are changes -> Event handler

Upvotes: 0

Views: 401

Answers (3)

Florian Schmidinger
Florian Schmidinger

Reputation: 4692

You can't do it with fields but with properties:

class SomeClass : INotifyPropertyChanged
{
    private string someProperty;
    public string SomeProperty 
    {
        get { return someProperty; }
        set { someProperty = value; OnPropertyChanged(); }
    }

    private void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate {};
}

Edit (.net 4.0)

class SomeClass : INotifyPropertyChanged
{
    private string someProperty;
    public string SomeProperty 
    {
        get { return someProperty; }
        set { someProperty = value; OnPropertyChanged("SomeProperty"); }
    }

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate {};
}

Edit (Winforms example)

public partial class Form1 : Form
{
    private SomeClass theObject = new SomeClass(); //keep a reference of the object.

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
       //here we do the binding... we want the 'Text' Property of the control to change if the 'SomeProperty' changes OnPropertyChanged
        textBox1.DataBindings.Add("Text",theObject,"SomeProperty",false,DataSourceUpdateMode.OnPropertyChanged);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        theObject.SomeProperty = "This works!"; //just a test button that changes the property...
    }
}

Upvotes: 1

Maarten
Maarten

Reputation: 22945

In addition to @Florian's answer, you can inject an implementation of the INotifyPropertyChanged interface at compile time using Fody.PropertyChanged.

Upvotes: 1

Georg
Georg

Reputation: 5771

Though I know that it is an often undesired practice here at Stack Overflow, you may find my project NMF Expressions interesting: http://nmfexpressions.codeplex.com/

Basically, the project aims to allow you to write such as follows:

var myObservedVariable = Observable.Expression(() => whatever you want)

In this scenario, myObservedVariable will be of INotifyValue<T> which provides a ValueChanged event. Alternatively, you can use the query syntax. Alternatively, you may have a look at other similar frameworks like Obtics, BindableLINQ or ContinuousLINQ. A comparison of the latter was done in Bindable Linq vs. Continuous Linq.

However, this only works under pretty strong assumptions like all the object models that you are working with completely support INotifyPropertyChanged and INotifyCollectionChanged.

Upvotes: 1

Related Questions