Observable collection Raise property changed

inotifypropertychangedobservablecollection

private ObservableCollection<Scores> _scores; 
    public ObservableCollection<Scores> Scores
    {
        get
        {
            return _scores;
        }
        set
        {
            _scores = value;
            RaisePropertyChanged("Scores");
            Recalculate();
        } 
    }

    public int RowNumber { get; set; }
    public string StudentId { get; set; }
    public string StudentName { get; set; }

    private double _studentAverage;
    public double StudentAverage
    {
        get
        {
            return _studentAverage;
        }
        set
        {
            _studentAverage = value;
            RaisePropertyChanged("StudentAverage");
        }
    }

    private string _gradeYear;
    public string GradeYear
    {
        get
        {
            return _gradeYear;
        }
        set
        {
            _gradeYear = value;
            RaisePropertyChanged("StudentGrade");
        }
    }


    private void Recalculate()
    {
        StudentAverage = (from score in Scores select score.Score).Sum();
    }

Hi, how can i get the notification when a score changes inside ObservableCollection so that i can recalculate.

Actually i am binding the whole Entity to a Gridview. Whenever a Score changes in the column i want my Total column to automatically calculate the Total and display.

Best Answer

Note 1

In a nutshell - you should subscribe to INotifyPropertyChanged.PropertyChanged event of all your "scores", and in the event handler you should recalc your TotalScore. But the problem is that you should also monitor changes in your Scores collection (if you need it, of course).

As a very useful helper you can try to use my Extended ObservableCollection. This class already contains ItemPropertyChangedEvent, so you should just write something like:

private ObservableCollectionEx<Scores> _scores; 

public ObservableCollectionEx<Scores> Scores
{
    get
    {
        return _scores;
    }
    set
    {
        if (_scores == value) return;
        if (_scores != null)
            _scores.ItemPropertyChanged -= OnItemPropertyChanged;
        _scores = value;
        if (_scores != null)
            _scores.ItemPropertyChanged += OnItemPropertyChanged;
        RaisePropertyChanged("Scores");
        Recalculate();
    } 
}

void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Score")
        Recalculate();
}

Note 2

Take a look also at this article. It will teach how to avoid "magic strings" in notifications (like RaisePropertyChanged("Scores") and e.PropertyName == "Score").

Note 3

Instead of

StudentAverage = (from score in Scores select score.Score).Sum();

it's better to use

StudentAverage = Scores.Sum(score => score.Score);

But this is not necessarily, this is just my style of coding :)

BTW, why it's mixed - "average" and "sum"? Is this mistake?

Related Topic