如何对DataGridView中添加的每一列求和



我创建了一个SubPODetailView.xaml,其中包括一个
SubPoDetailViewModel.cs。该模型又包含一个用于数据网格的
SubInvoice.cs和用于其他详细信息的SubPO.cs。我所拥有的是,每次我加一行;金额";列显示在总TextBlock中。

运行程序的查看页面截图

SubPODetailView.xaml

<DataGrid ItemsSource="{Binding Invoices}" 
SelectedItem="{Binding SelectedInvoice,Mode=TwoWay}"
AutoGenerateColumns="False" RowHeaderWidth="0" >

<DataGrid.Columns>
<DataGridTextColumn Header="Invoices" Width="*"
Binding="{Binding InvoiceName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTemplateColumn Header="Date" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding Date,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Amount" Width="*" Binding="{Binding Amount,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTemplateColumn Header="Status" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Status,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>

</DataGrid>
<TextBlock Text="{Binding Total}" Margin="10,0" Background="#FFC9CD7D" Foreground="Black"/>

SubPODetailViewModel.cs

public class SubPODetailViewModel : DetailViewModelBase, ISubPODetailViewModel
{
private ISubPORepository _subPORepository;
private IMessageDialogService _messageDialogService;
private SubPOWrapper _subPO;
private SubInvoiceWrapper _selectedInvoice;
public SubPODetailViewModel(IEventAggregator eventAggregator,
IMessageDialogService messageDialogService,
ISubPORepository subPORepository) : base(eventAggregator)
{
_subPORepository = subPORepository;
_messageDialogService = messageDialogService;
AddInvoiceCommand = new DelegateCommand(OnAddInvoiceExecute);
RemoveInvoiceCommand = new DelegateCommand(OnRemoveInvoiceExecute, OnRemoveInvoiceCanExecute);
Invoices = new ObservableCollection<SubInvoiceWrapper>();
}
// SubPOWrapper for SubPO.cs class
public SubPOWrapper SubPO
{
get { return _subPO; }
private set
{
_subPO = value;
OnPropertyChanged();
}
}
// SubInvoiceWrapper for SubInvoice.cs class
public SubInvoiceWrapper SelectedInvoice
{
get { return _selectedInvoice; }
set
{
_selectedInvoice = value;
OnPropertyChanged();
((DelegateCommand)RemoveInvoiceCommand).RaiseCanExecuteChanged();
}
}
public ICommand AddInvoiceCommand { get; }
public ICommand RemoveInvoiceCommand { get; }
public ObservableCollection<SubInvoiceWrapper> Invoices { get; }
public override async Task LoadAsync(int? subPOId)
{
var subPO = subPOId.HasValue
? await _subPORepository.GetByIdAsync(subPOId.Value)
: CreateNewSubPO();
InitializeSubPO(subPO);
InitializeSubInvoice(subPO.Invoices);
}
private SubPO CreateNewSubPO()
{
var subPO = new SubPO();
_subPORepository.Add(subPO);
return subPO;
}
private void InitializeSubInvoice(ICollection<SubInvoice> invoices)
{
foreach (var wrapper in Invoices)
{
wrapper.PropertyChanged -= SubInvoiceWrapper_PropertyChanged;
}
Invoices.Clear();
foreach (var subInvoice in invoices)
{
var wrapper = new SubInvoiceWrapper(subInvoice);
Invoices.Add(wrapper);
wrapper.PropertyChanged += SubInvoiceWrapper_PropertyChanged;
}
}
private void SubInvoiceWrapper_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (!HasChanges)
{
HasChanges = _subPORepository.HasChanges();
}
if (e.PropertyName == nameof(SubInvoiceWrapper.HasErrors))
{
((DelegateCommand)SaveCommand).RaiseCanExecuteChanged();
}
}
private void InitializeSubPO(SubPO subPO)
{
SubPO = new SubPOWrapper(subPO);
SubPO.PropertyChanged += (s, e) =>
{
if (!HasChanges)
{
HasChanges = _subPORepository.HasChanges();
}
if (e.PropertyName == nameof(SubPO.HasErrors))
{
((DelegateCommand)SaveCommand).RaiseCanExecuteChanged();
}
};
((DelegateCommand)SaveCommand).RaiseCanExecuteChanged();
if (SubPO.Id == 0)
{
// Little trick to trigger the validation
SubPO.Title = "";
}
}
protected override void OnDeleteExecute()
{
var result = _messageDialogService.ShowOkCancelDialog($"Do you really want to delete the Subcontractor {SubPO.Title}?", "Question");
if (result == MessageDialogResult.OK)
{
_subPORepository.Remove(SubPO.Model);
_subPORepository.SaveAsync();
RaiseDetailDeletedEvent(SubPO.Id);
}
}
protected override bool OnSaveCanExecute()
{
return SubPO != null
&& !SubPO.HasErrors
&& Invoices.All(i=>!i.HasErrors)
&& HasChanges;
}
protected override async void OnSaveExecute()
{
await _subPORepository.SaveAsync();
HasChanges = _subPORepository.HasChanges();
RaiseDetailSavedEvent(SubPO.Id, SubPO.Title);
}
private void OnAddInvoiceExecute()
{
var newInvoice = new SubInvoiceWrapper(new SubInvoice());
newInvoice.PropertyChanged += SubInvoiceWrapper_PropertyChanged;
Invoices.Add(newInvoice);
SubPO.Model.Invoices.Add(newInvoice.Model);
//newInvoice.InvoiceName = "";
newInvoice.Date = DateTime.Now.Date;
// Trigger validation :-) 
}
private void OnRemoveInvoiceExecute()
{
SelectedInvoice.PropertyChanged -= SubInvoiceWrapper_PropertyChanged;
_subPORepository.RemoveInvoice(SelectedInvoice.Model);
Invoices.Remove(SelectedInvoice);
SelectedInvoice = null;
HasChanges = _subPORepository.HasChanges();
((DelegateCommand)SaveCommand).RaiseCanExecuteChanged();
}
private bool OnRemoveInvoiceCanExecute()
{
return SelectedInvoice !=null;
}
}
}

注意:要将整个程序检查为zip文件,请点击此处(只需单击慢速下载,然后继续(:http://www.filefactory.com/file/681du53ow7us/SubBVZip.zip

更新

我在运行程序时遇到的问题的屏幕截图,如何在不添加另一行的情况下对行求和。

SubPODetailView的最后一个TextBlock已经绑定到视图模型中的Total属性。在视图模型上创建属性Total,并将CollectionChanged处理程序添加到Invoices:

public SubPODetailViewModel(IEventAggregator eventAggregator,
IMessageDialogService messageDialogService,
ISubPORepository subPORepository) : base(eventAggregator)
{
...
Invoices.CollectionChanged += Invoices_CollectionChanged;
}
private void Invoices_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Total = Invoices.Sum(x => x.Amount);
}
private decimal _total;
public decimal Total
{
get => _total;
set {
_total = value;
OnPropertyChanged();
}
}

最新更新