[英]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? 我怎样才能做到这一点?
<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; }
}
Cantinou, 坎蒂努,
I see two ways : 我看到两种方式:
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(); } }
} }
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.