与ObservableCollection绑定的dataGrid中的计算列

时间:2015-10-13 03:08:22

标签: c# wpf mvvm datagrid

我正在构建一个WPF - MVVM应用程序。我有一个与ObservableCollection绑定的dataGrid。

在这个集合中,我有一列数量,一列价格/最小起订量和一列必须逻辑上等于数量*价格=总计。

因此,每次添加行并填写数量和价格时,必须计算总计列。

我该怎么做?

查看

    <DataGrid x:Name="dataGridInvoice" Margin="5" Grid.Row="1" 
                          ItemsSource="{Binding Collection}" 
                          AutoGenerateColumns="False"
                          SelectedItem="{Binding Selected, Mode=TwoWay}" 
                          SelectionMode="Extended" SelectionUnit="FullRow" AddingNewItem="dataGridInvoice_AddingNewItem">
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="SuppNb" Binding="{Binding suppInvNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                        <DataGridTextColumn Header="Shop" Binding="{Binding shop, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                        <DataGridTextColumn Header="Date" Binding="{Binding date, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                        <DataGridTextColumn Header="Supplier" Binding="{Binding supplier, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                        <DataGridComboBoxColumn Header="Ref Supplier"
                                                    ItemsSource="{Binding Products, Mode=OneWay, Source={StaticResource supplier}}"
                                                    DisplayMemberPath="refsup" 
                                                    SelectedValueBinding="{Binding refSupp}" 
                                                    SelectedValuePath="refsup"
                                                    Width="*"/>
                        <DataGridTextColumn Header="Description" Binding="{Binding description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                        <DataGridComboBoxColumn Header="Unit"
                                                    ItemsSource="{Binding Collection, Mode=OneWay, Source={StaticResource unit}}"
                                                    DisplayMemberPath="unit1" 
                                                    SelectedValueBinding="{Binding unit}" 
                                                    SelectedValuePath="idunit"
                                                    Width="*"/>
                        <DataGridTextColumn Header="Quantity" Binding="{Binding quantity, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                        <DataGridTextColumn Header="Prix/MOQ" Binding="{Binding unitPrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                        <DataGridTextColumn Header="Total Price" Binding="{Binding totalPrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
                    </DataGrid.Columns>
</DataGrid>

视图模型

public class InvoiceViewModel : ViewModelBase
{
    public Context ctx = new Context();
    public InvoiceViewModel()
    {
        Get(false);
    }

    private ObservableCollection<Invoice> collection;
    public ObservableCollection<Invoice> Collection
    {
        get
        {
            return collection;
        }
        set
        {
            collection = value;
            OnPropertyChanged("Collection");
        }
    }

    private Invoice _selected;
    public Invoice Selected
    {
        get
        {
            return _selected;
        }
        set
        {
            _selected = value;
            OnPropertyChanged("Selected");
        }
    }

    private void Get(bool loadDataFirst)
    {
        if(loadDataFirst)
            ctx.Invoices.Load();
        Collection = ctx.Invoices.Local;
    }

    private void Save()
    {
        ctx.SaveChanges();
    }

    private void Delete()
    {
        var id = Selected;
        var invoice = (from i in ctx.Invoices
                       where i.idInvoice == id.idInvoice
                       select i).SingleOrDefault();
        Collection.Remove(invoice);
    }

    private Invoice _currentItem;
    public Invoice CurrentItem
    {
        get
        {
            return _currentItem;
        }
        set
        {
            _currentItem = value;
            OnPropertyChanged("CurrentItem");
        }
    }

    #region "Command"

    private ICommand saveCommand;
    private ICommand removeCommand;

    public ICommand SaveCommand
    {
        get
        {
            return saveCommand ?? (saveCommand = new RelayCommand(p => this.Save(), p => this.CanSave()));
        }
    }
    private bool CanSave()
    {
        return true;
    }
    #endregion
}

模型

public partial class Invoice
    {
        public int idInvoice { get; set; }
        public string invNumber { get; set; }
        public string suppInvNumber { get; set; }
        public Nullable<int> supplier { get; set; }
        public Nullable<int> shop { get; set; }
        public Nullable<System.DateTime> date { get; set; }
        public string refSupp { get; set; }
        public string description { get; set; }
        public string unit { get; set; }
        public Nullable<decimal> quantity { get; set; }
        public Nullable<decimal> unitPrice { get; set; }
        public Nullable<decimal> totalPrice { get; set; }

        public virtual foodSupplier foodSupplier { get; set; }
        public virtual shop shop1 { get; set; }
    }

1 个答案:

答案 0 :(得分:0)

Cantinou,

我看到两种方式:

  1. 更改Invoice类,以便它引发事件

    public partial class Invoice:ViewModelBase {     // ....     私人可空数量;

    public Nullable<decimal> Quantity
    {
        get { return quantity; }
        set
        {
            quantity = value;
            base.OnPropertyChanged();
            if (quantity.HasValue && unitPrice.HasValue)
                TotalPrice = quantity * unitPrice;
        }
    }
    private Nullable<decimal> unitPrice;
    
    public Nullable<decimal> UnitPrice
    {
        get { return unitPrice; }
        set
        {
            unitPrice = value;
            base.OnPropertyChanged();
            if (quantity.HasValue && unitPrice.HasValue)
                TotalPrice = quantity * unitPrice;
        }
    }
    private Nullable<decimal> totalPrice;
    
    public Nullable<decimal> TotalPrice
    {
        get { return totalPrice; }
        set
        {
            totalPrice = value;
            base.OnPropertyChanged();
        }
    }
    

    }

  2. 在GUI中放置一些代码以检测版本的结尾并制作产品。我认为计算价格的观点不是负责任的......但从技术上讲,这是可能的。

    private void DataGridInvoiceRowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        if (e.EditAction == DataGridEditAction.Commit) {
            Invoice invoice = e.Row.DataContext as Invoice;
            // update Invoice object if needed
            if (invoice != null)
            {
                // ....
            }
        }
    }
    private void DataGridInvoiceCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
       // ...
    }
    
  3. 此致