-1

私は を持ってObservableCollectionStudentsます。各 Student には Grade プロパティがあります。AverageGradeボタンを押したりタイマーを作成したりしなくても、(すべての学生の) プロパティが機能するようにしたいと考えています。DependencyPropertyこの読み取り専用AverageGradeプロパティに hereを使用するにはどうすればよいですか?

Student.cs

using System.ComponentModel;
using System.Windows;
using System;

namespace WpfApplication17.Models
{
    class Student : INotifyPropertyChanged
    {
        #region Constructors

        public Student(string firstName, string lastName, double grade)
                                {
            this.FirstName = firstName;
            this.LastName = lastName;
                this.Grade = grade;
        }

                        #endregion

        #region Properties

                private string _firstName;

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }

        private string _lastName;

        public string LastName
        {
            get { return _lastName; }
                            set
                {
                _lastName = value;
                OnPropertyChanged("LastName");
                    }
            }

        private double _grade;

        public double Grade
        {
        get { return _grade; }
        set
        {
            _grade = value;
            OnPropertyChanged("Grade");
        }
    }

    #endregion

    #region PropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

}

MainWindowViewModel

using WpfApplication17.ViewModel;
using System.Collections.ObjectModel;
using WpfApplication17.Models;

namespace WpfApplication17.ViewModels
{
    class MainWindowViewModel : ViewModelBase
    {
        #region Constructors

        public MainWindowViewModel()
        {
            Students = new ObservableCollection<Student>();
            Students.Add(new Student("Frank", "Sinatra", 7));
            Students.Add(new Student("Bart", "Simpson", 6));
        }

        #endregion

        #region Properties

        private ObservableCollection<Student> _students;

        public ObservableCollection<Student> Students
        {
            get { return _students; }
            set
            {
                _students = value;
                OnPropertyChanged("Students");
            }
        }

        public double AverageGrade
        {
            get { return GetAverageGrade(); }
        }

        public double GetAverageGrade()
        {
            double sum = 0;

            foreach (Student s in Students)
                sum += s.Grade;

            return sum / (double)Students.Count;
        }

        #endregion
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication17.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Horizontal">
        <DataGrid ItemsSource="{Binding Students}" />
        <Label Content="Average Grade:" />
        <Label Content="{Binding AverageGrade}" />
    </StackPanel>
</Window>
4

1 に答える 1

1

なぜDPが必要なのか、通常のVMプロパティがこれを処理するようです。必要なのは、新しい学生が追加されるか、既存の学生の成績が変更されるたびに、AverageGrade を更新する必要があることです。

多分このアプローチを試してください:

    class MainWindowViewModel 
{
    #region Constructors

    public MainWindowViewModel()
    {
        Students = new ObservableCollection<Student>();
        Students.Add(new Student("Frank", "Sinatra", 7));
        Students.Add(new Student("Bart", "Simpson", 6));

        Students.CollectionChanged += (s, e) => AverageGrade = this.GetAverageGrade();

        foreach (var student in Students)
        {
            student.PropertyChanged += OnStudentPropertyChanged;
        }

        AverageGrade = this.GetAverageGrade();
    }

    private void OnStudentPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Grade")
        {
            AverageGrade = this.GetAverageGrade();
        }
    }

    #endregion

    #region Properties

    private ObservableCollection<Student> _students;

    public ObservableCollection<Student> Students
    {
        get { return _students; }
        set
        {
            _students = value;
            OnPropertyChanged("Students");
        }
    }

    private double average;
    public double AverageGrade
    {
        get
        {
            return this.average;
        }
        set
        {
            this.average = value;
            OnPropertyChanged("AverageGrade");
        }
    }

    public double GetAverageGrade()
    {
        return this.Students.Sum(s => s.Grade) / Students.Count;
    }

    #endregion

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
于 2012-12-23T10:40:22.963 に答える