0

I display dataGrid in WPF and entity framework, column 2 has a price per unit column 3 has the quantity (column 4 has the discount), I want column 5 will be the summary. My question is how I can capture the third column and calculate the change to the total column

Here is the code How do I display the data

          <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
    }

}

I tried several ways, but no results

Thanks in advance for help

user1095549
  • 1,339
  • 3
  • 12
  • 14

1 Answers1

1

If you are using CodeFirst to create your entities

Since you are using entities, you can create an unmapped (use the [NotMapped] attribute) property in your entity class that computes the values and bind a column to that property. Since Entity classes implement INotifyPropertyChanged by default, everything should perform without much more work, although you may need to put a PropertyChangedEventHandler call on the other three (Price, Quantity, Discount) to tell the UI to update the value of Total.

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

Since you are not going to be setting the Total in code, the property is ReadOnly.

If you are using an EDMX and designer to create your entities

Since you are using an EDMX (through the designer), you will need to add the property via a partial class.

  1. Create a new class named the same as the Entity that you want to modify (Job in this case I think).
  2. Mark the class declaration as partial. In this case, you can now add methods to a generated class.
  3. Add the above Total property (editing the formula as necessary).
  4. You will likely have to override the PriceChanged, QuantityChanged, and DiscountChanged methods and add a property changed event handler call specifying the total property (e.g. base.OnPropertyChanged("Total");) so that the UI knows to update.

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

Update

I got your solution, and looked at it. Your entities are generated via T4 template. I don't have much experience with those, but for the most part, the answer above in the section "If you are using an EDMX and designer to create your entities" still sort of applies. You need to modify the the T4 template to implement property changed notifications in such as way as you can get to the property changed method, and put the Total property (without the NotMapped attribute) in your partial class. The answer supplied here looks like it is relevant and correct (based on what knowledge I have about the subject).

Community
  • 1
  • 1
CodeWarrior
  • 7,388
  • 7
  • 51
  • 78
  • Sorry, but I did not understand how I do it? – user1095549 May 22 '13 at 14:14
  • How are you generating your entities? Are you using the Entity Framework Designer? – CodeWarrior May 22 '13 at 14:29
  • Because implementation is slightly different depending on how you create your entities. Please see the edit to my post above. – CodeWarrior May 22 '13 at 15:06
  • First thanks for the help , Sorry, but after many attempts above code does not work. the OnPropertyChanged ("Total"); does not belong to the calss, it could be related to VS2012? EF5? – user1095549 May 23 '13 at 21:43
  • Your entities should be inherited from EntityObject. EntityObject implements INotifyPropertyChanged and has a method OnPropertyChanged which should be called from a derived class using the `base` class. If your entities are not inheriting from EntityObject, what *are* they inheriting from? – CodeWarrior May 23 '13 at 21:45
  • If I inherit from EntityObject I get EOROR The invocation of the constructor on type 'Contractor_Project.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position – user1095549 May 23 '13 at 22:24
  • I did not mean that you should explicitly inherit from EntityObject. If you are using an EDM generated via the designer, your entities should already inherit from EntityObject(See link at the bottom of my post). If you are not using the designer to generate your EDM (i.e. using CodeFirst), then your entities will not inherit from EntityObject. Please let me know that you tried the 4 steps under the heading "If you are using an EDMX and designer to create your entities" and that you tried calling base.OnPropertyChanged from in a partial class that is named the same as your Entity class. – CodeWarrior May 24 '13 at 06:01
  • When you mouse over base, what does it resolve as? If it is EntityObject, then OnPropertyChanged should work as EntityObject implements INotifyPropertyChanged. – CodeWarrior May 28 '13 at 14:12
  • Sorry, I can send you this file and see what does not work there? Thanks for all your help and patience – user1095549 May 28 '13 at 18:49
  • Alright, send it to balthasar10 at yahoo.com, and I will take a look at it. Are you going to send the whole solution? That would be best as it would give me better context. – CodeWarrior May 29 '13 at 15:09
  • Sorry, but you have received the file? – user1095549 Jun 02 '13 at 14:41
  • Yes, see the update section in my answer above. Since you are using a T4 template to generate your classes, it looks like you will need to modify the template to generate property changed methods for you. Otherwise everything else should work for you (but you will not need the NotMapped attribute). If the linked answer is not sufficient, search around for `T4 Template INotifyPropertyChanged`. – CodeWarrior Jun 03 '13 at 13:38