Как связать данные агрегатной функции (например, сумма) в WPF? - PullRequest
0 голосов
/ 24 августа 2018

Представьте, что у меня есть следующий класс, который реализует INotifyPropertyChanged.(Для краткости я не показываю код, который вызывает события PropertyChanged, но представьте, что это делает каждое свойство.)

public class Employee : INotifyPropertyChanged
{
    public string Title { get; set; }
    public string Department { get; set; }
    public double Salary { get; set; }
}

Теперь, скажем, у меня четыре сотрудника:

     Title         Department    Salary
     -----------------------------------
(1)  Professor     Math           90,000
(2)  Professor     CompSci       120,000
(3)  Instructor    Math           50,000
(4)  Instructor    CompSci        60,000

Я хотел бы создать таблицу с использованием WPF, как показано ниже:

Title         Math      CompSci    Total
------------------------------------------
Professor     90,000    120,000    210,000
Instructor    50,000     60,000    110,000

Она перераспределяет сотрудников по названию, показывая их зарплаты для каждого отдела в отдельных столбцах.В последнем столбце показана общая зарплата на заголовок.

Кроме того, я бы хотел, чтобы пользователь мог взаимодействовать с таблицей, например, добавлять или удалять сотрудника или изменять чью-либо зарплату (ипоэтому автоматически обновляю итоговое значение).

Я смог сделать это, воссоздавая всю таблицу каждый раз, когда происходит изменение.Но я хотел бы иметь возможность делать это более эффективно (например, обновлять итоговые данные только при изменении зарплаты).

Я пытался это сделать, но код очень быстро запутывается.Моя модель представления должна прослушивать изменения коллекции в Employees, и всякий раз, когда кто-то добавляется, она должна прослушивать свою зарплату, чтобы обновить Итог.Трудно следить за тем, что происходит, и я думаю, что позже это будет кошмар обслуживания.

Мне бы хотелось, чтобы был способ связать общее количество и автоматически отслеживать все необходимые изменения.Вот некоторый выдуманный код, чтобы показать, что я имею в виду:

<TextBlock Text="{Binding Employees, Aggregate=Sum, Property=Salary}" />

Я знаю, что этого не существует, но есть ли какой-нибудь простой способ реализовать то, что я пытаюсь сделать, который понятен и понятен?Это не должно быть в XAML.Я в порядке с программным решением, пока ясно, что происходит.

1 Ответ

0 голосов
/ 24 августа 2018

Я предполагаю, что где-то у вас есть мастер-класс со списком сотрудников, таких как:

public ObservableCollection<Employee> Employees { get; private set; }

что вы добавляете свои данные.

Теперь вы можете создать новый выходной класс из него следующим образом:

public class Summary : ViewModelBase
{
    private string _Title;
    public string Title
    {
        get { return _Title; }
        set { Set(ref _Title, value); }
    }

    private decimal _MathSalary;
    public decimal MathSalary
    {
        get { return _MathSalary; }
        set { Set(ref _MathSalary, value); }
    }

    private decimal _CompSciSalary;
    public decimal CompSciSalary
    {
        get { return _CompSciSalary; }
        set { Set(ref _CompSciSalary, value); }
    }

    private decimal _Total;
    public decimal Total
    {
        get { return _Total; }
        set { Set(ref _Total, value); }
    }
}

и затем вы можете создать общее свойство класса, которое будет получено только с помощью этого запроса linq:

public List<Summary> EmpSum
    {
        get
        {
            return this.Employees.GroupBy(x => x.Title).Select(y => new Summary { Title = y.First().Title, MathSalary = y.Where(s => s.Department == "Math").Sum(s => s.Salary), CompSciSalary = y.Where(s => s.Department == "CompSci").Sum(s => s.Salary), Total = y.Sum(s => s.Salary) }).ToList();
        }
    }

Я использую MVVMLight (ViewModelBase), но вы можете сделать свой собственный код уведомления. Просто нужно поднять свойство пропущенное ("EmpSum") при добавлении / удалении. Изменить основной список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...