Ячейка суммы wpf dataGrid с сущностями

Я отображаю dataGrid в WPF и структуре сущностей, в столбце 2 указана цена за единицу, в столбце 3 указано количество (в столбце 4 есть скидка), я хочу, чтобы столбец 5 был сводным. Мой вопрос в том, как я могу зафиксировать третий столбец и рассчитать изменение общего столбца.

Вот код Как мне отобразить данные

          <DataGrid.Columns>
            <DataGridComboBoxColumn x:Name="ddd"  Header="Expenses" Width="*" SelectedValueBinding="{Binding Path=ExpensesId}" DisplayMemberPath="ExpensesName" SelectedValuePath="ExpensesTypeId"/>
            <DataGridTextColumn Header="price" Width="*" Binding="{Binding Path=Expenses.PricePorEach}"/>
            <DataGridTextColumn Header="quantity" Width="50"  Binding="{Binding Path=Quantity}"/>
            <DataGridTextColumn Header="discount" Width="*" Binding="{Binding Path=Discount}"/>
            <DataGridTextColumn Header="Total" Width="*" Binding="{Binding Path=Total}"/>
        </DataGrid.Columns>
    </DataGrid>

      ContractorEntities ce = new ContractorEntities();
    public MainWindow()
    {
        InitializeComponent();
        BindData();
    }
    private void BindData()
    {
        var dataSource = new  ObservableCollection<Jobs>(ce.Jobs);
        dataSource.CollectionChanged += CollectionChanged;
        dg.ItemsSource = dataSource;
        dg.DataContext = dataSource;

    }
    private void CollectionChanged(object sender,  NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
            foreach (Jobs job in e.NewItems)
                  ce.Jobs.Add(job);

        else if (e.Action == NotifyCollectionChangedAction.Remove)
            foreach (Jobs jobin e.OldItems)
                ce.Jobs.Remove(job);
    }
    private void saveButton_Click(object sender, RoutedEventArgs e)
    {
        ce.SaveChanges();
    }
    [NotMapped]
    public decimal? Total
    {
        get
        {
            return (Price * Quantity) - Discount;
        }
        set { }
    }

    public void OnDiscountChanged()
    {
        base.OnPropertyChanged("Total");//This line is not known
    }

    public void OnPriceChanged()
    {
        base.OnPropertyChanged("Total");//This line is not known
    }

    public void OnQuantityChanged()
    {
        base.OnPropertyChanged("Total");//This line is not known
    }

}

Я пробовал несколько способов, но безрезультатно

Заранее спасибо за помощь


person user1095549    schedule 22.05.2013    source источник


Ответы (1)


Если вы используете CodeFirst для создания своих сущностей

Поскольку вы используете сущности, вы можете создать несопоставленное (используйте атрибут [NotMapped]) свойство в своем классе сущностей, которое вычисляет значения и привязывает столбец к этому свойству. Поскольку классы Entity реализуют INotifyPropertyChanged по умолчанию, все должно выполняться без дополнительной работы, хотя вам может потребоваться поместить вызов PropertyChangedEventHandler в остальные три (Price, Quantity, Discount), чтобы указать пользовательскому интерфейсу обновить значение Total.

[NotMapped]
public int Total
{
    get
    {
        return (Price * Quantity) - Discount;
    {
}

Поскольку вы не собираетесь устанавливать значение Total в коде, свойство доступно только для чтения.

Если вы используете EDMX и конструктор для создания своих сущностей

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

  1. Создайте новый класс с тем же именем, что и объект, который вы хотите изменить (я думаю, в данном случае Job).
  2. Отметьте объявление класса как частичное. В этом случае теперь вы можете добавлять методы в сгенерированный класс.
  3. Добавьте указанное выше свойство Total (при необходимости отредактируйте формулу).
  4. Скорее всего, вам придется переопределить методы PriceChanged, QuantityChanged и DiscountChanged и добавить вызов обработчика события изменения свойства с указанием общего свойства (например, base.OnPropertyChanged("Total");), чтобы пользовательский интерфейс знал об обновлении.

    public partial class Job
    {
        public void OnDiscountChanged()
        {
            base.OnPropertyChanged("Total");
        }
    
        public void OnPriceChanged()
        {
            base.OnPropertyChanged("Total");
        }
    
        public void OnQuantityChanged()
        {
            base.OnPropertyChanged("Total");
        }
    }
    

Обновлять

Я получил ваше решение и посмотрел на него. Ваши объекты генерируются с помощью шаблона T4. У меня нет большого опыта работы с ними, но по большей части ответ выше в разделе «Если вы используете EDMX и дизайнер для создания своих сущностей» по-прежнему применим. Вам необходимо изменить шаблон T4, чтобы реализовать уведомления об изменении свойства таким образом, чтобы вы могли получить метод изменения свойства, и поместить свойство Total (без атрибута NotMapped) в свой разделяемый класс. Ответ приведен здесь выглядит уместным и правильным (исходя из того, что я знаю о предмете).

person CodeWarrior    schedule 22.05.2013
comment
Извините, но я не понял, как я это делаю? - person user1095549; 22.05.2013
comment
Как вы генерируете свои сущности? Вы используете Entity Framework Designer? - person CodeWarrior; 22.05.2013
comment
Потому что реализация немного отличается в зависимости от того, как вы создаете свои сущности. Пожалуйста, смотрите редактирование моего поста выше. - person CodeWarrior; 22.05.2013
comment
Во-первых, спасибо за помощь. Извините, но после многих попыток приведенный выше код не работает. OnPropertyChanged (Всего); не относится к классу, это может быть связано с VS2012? EF5? - person user1095549; 24.05.2013
comment
Ваши сущности должны быть унаследованы от EntityObject. EntityObject реализует INotifyPropertyChanged и имеет метод OnPropertyChanged, который следует вызывать из производного класса с использованием класса base. Если ваши объекты не наследуются от EntityObject, от чего они наследуют? - person CodeWarrior; 24.05.2013
comment
Если я наследую от EntityObject, я получаю EOROR. Вызов конструктора типа «Contractor_Project.MainWindow», который соответствует указанным ограничениям привязки, вызвал исключение. Номер строки «3» и позиция строки - person user1095549; 24.05.2013
comment
Я не имел в виду, что вы должны явно наследовать от EntityObject. Если вы используете EDM, созданный с помощью дизайнера, ваши сущности уже должны наследоваться от EntityObject (см. ссылку внизу моего поста). Если вы не используете конструктор для создания своего EDM (т. е. используете CodeFirst), то ваши сущности не будут наследоваться от EntityObject. Пожалуйста, дайте мне знать, что вы выполнили 4 шага под заголовком Если вы используете EDMX и конструктор для создания своих сущностей, и что вы пытались вызвать base.OnPropertyChanged из частичного класса, имя которого совпадает с вашим классом Entity. - person CodeWarrior; 24.05.2013
comment
Когда вы наводите курсор мыши на базу, как она разрешается? Если это EntityObject, то OnPropertyChanged должен работать, поскольку EntityObject реализует INotifyPropertyChanged. - person CodeWarrior; 28.05.2013
comment
Извините, я могу отправить вам этот файл и посмотреть, что там не работает? Спасибо за вашу помощь и терпение - person user1095549; 28.05.2013
comment
Хорошо, пришлите его balthasar10 на yahoo.com, я посмотрю. Вы собираетесь отправить все решение? Это было бы лучше, поскольку это дало бы мне лучший контекст. - person CodeWarrior; 29.05.2013
comment
Извините, а вы получили файл? - person user1095549; 02.06.2013
comment
Да, см. раздел обновлений в моем ответе выше. Поскольку вы используете шаблон T4 для создания своих классов, похоже, вам нужно будет изменить шаблон, чтобы сгенерировать для вас методы с измененными свойствами. В противном случае все остальное должно у вас работать (но атрибут NotMapped вам не понадобится). Если связанного ответа недостаточно, найдите T4 Template INotifyPropertyChanged. - person CodeWarrior; 03.06.2013