How to notify a "higher" class that something in a "lower" class has changed? Or: publish/subscribe the other way round

StackOverflow https://stackoverflow.com/questions/22857503

Pregunta

Suppose you have two classes:

public class A
{
    int x = 0;
    public void Increase()
    {
        x++;
    }
}

public class B
{
    A a;
    private void DoSomething();
}

Is there a way for B to be "messaged" and execute DoSomething() when anything has changed in a (i.e. x has increased)? I know how I could make a subscribe to B, such that if B does RaiseSomeEvent(..), a reacts, but not the other way round.

Background: I'm trying to create a custom control

public class BattleshipCanvas : Canvas
{
    public BSGrid BattleshipGrid {...}
    ...
}

that should redraw once anything inside the BattleshipGrid (BSGrid is a class encapsulating a two-dimensional array) changes, where BattleshipGrid will be bound to a certain BSGrid in the ViewModel. I thought about adding an event to BSGrid that is raised whenever I modify its data, but I don't know how to notify the BattleshipCanvas of that event.

I hope I could make it a little clear (it's hard for me to express what I want exactly here) and understandable, but if there arise any questions, feel free to comment and I'll try to answer them. Thanks!

¿Fue útil?

Solución

You may be looking for events in c#. In your specific case you may like to make use of the INotifyPropertyChanged Interface. You can use it to inform other classes by events if a property inside the implementing class has changed. This is also the base to use binding in your project later on.

public class A: INotifyPropertyChanged
{
    //Event used to announce a change inside a property of your class
    public event PropertyChangedEventHandler PropertyChanged;

    int _x = 0;
    public int X
    {
        get { return _x; }
        set 
        {
            if (_x != value)
            {
                _x = value;
                OnPropertyChanged("X"); //invokes the event.
            }

        }
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) //make sure somebody subscribed to the event
            handler.Invoke(this, new PropertyChangedEventArgs(propertyName)); //this calls all eventhandler methods which subscribed to your classes PropertyChanged event.
    }


    public void Increase()
    {
        X++;    //use the property to invoke a property changed event.
    }



}

public class B
{
    A a;

    public B()
    {
        a = new A();
        a.PropertyChanged += new PropertyChangedEventHandler(a_PropertyChanged);    //subscribe up to the event. (use -= to unsubscribe)
        a.Increase()
    }

    //Catch the event
    void a_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        //execute what you would like to do.
        //you can use e.PropertyName to lookup which property has actually changed.
        DoSomething();
    }

    private void DoSomething(){}
}

Otros consejos

Events are probably the way to go. You can make any class in your project react to any event being raised in your program, no matter where the event is created/handled.

In your instance, it looks like you don't even need to send over any custom EventArgs.

The most simple example I could find of this is here:

http://timok.tumblr.com/post/57441520214/simplistic-event-example-in-c

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top