简体   繁体   English

绑定了ObservableCollection的dataGrid中的计算列

[英]Calculated column in a dataGrid bound with a ObservableCollection

I'm building a WPF - MVVM application. 我正在构建WPF-MVVM应用程序。 I have a dataGrid bound with a ObservableCollection. 我有一个与ObservableCollection绑定的dataGrid。

In this collection I have a column Quantity,a column Price/MOQ and a column Total that has to be logicaly equal to Quantity * Price = Total. 在此集合中,我有一列“数量”,一列“价格/最小起订量”和一列“合计”,在逻辑上必须等于“数量*价格=合计”。

So each time I add a row and fill Quantity and Price, Total column has to be calculated. 因此,每次我添加一行并填充“数量和价格”时,都必须计算“总计”列。

How can I do that? 我怎样才能做到这一点?

View 视图

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

ViewModel 视图模型

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
}

Model 模型

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

Cantinou, 坎蒂努,

I see two ways : 我看到两种方式:

  1. Change the Invoice class so that it raises events 更改发票类,使其引发事件

    public partial class Invoice : ViewModelBase { // .... private Nullable quantity; 公共部分类发票:ViewModelBase {// .... private可空数量;

     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. Put some code in your GUI to detect end of edition and make product. 在您的GUI中放入一些代码以检测版本结束并生产产品。 I think it 's not the responsability of the view to compute prices,... but technically it is possible. 我认为这不是计算价格的责任,但是从技术上讲,这是可能的。

     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) { // ... } 

Regards 问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM