This example demonstrates how to calculate the total summary dynamically in batch edit mode when the grid's HighlightDeletedRows property is enabled.
Overview
Create a Custom Summary Item
Add a total summary item for the corresponding column. Use the item's Tag property to identify the summary item and get its value.
ASPx<TotalSummary>
<dx:ASPxSummaryItem SummaryType="Sum" FieldName="C2" Tag="C2_Sum" />
</TotalSummary>
C#protected object GetTotalSummaryValue() {
ASPxSummaryItem summaryItem = Grid.TotalSummary.First(i => i.Tag == "C2_Sum");
return Grid.GetTotalSummaryValue(summaryItem);
}
Replace the summary item with a custom footer template.
ASPx<dx:GridViewDataSpinEditColumn Width="100" FieldName="C2">
<FooterTemplate>
Sum =
<dx:ASPxLabel ID="ASPxLabel1" runat="server" ClientInstanceName="labelSum" Text='<%# GetTotalSummaryValue() %>' />
</FooterTemplate>
</dx:GridViewDataSpinEditColumn>
Handle the grid's client-side BatchEditEndEditing and BatchEditRowDeleting events. In handlers, use the grid's batchEditApi.GetCellValue method to get initial cell values and rowValues
argument property to get new cell values. Then recalculate the summary value and assign it to the label.
JavaScriptfunction OnBatchEditEndEditing(s, e) {
CalculateSummary(s, e.rowValues, e.visibleIndex, false);
}
function CalculateSummary(grid, rowValues, visibleIndex, isDeleting) {
var originalValue = grid.batchEditApi.GetCellValue(visibleIndex, "C2");
var newValue = rowValues[(grid.GetColumnByField("C2").index)].value;
var dif = isDeleting ? -newValue : newValue - originalValue;
labelSum.SetValue((parseFloat(labelSum.GetValue()) + dif).toFixed(1));
}
function OnBatchEditRowDeleting(s, e) {
CalculateSummary(s, e.rowValues, e.visibleIndex, true);
}
Create a Custom Recovery Button
Use the command column's CustomButtons property to create a custom Recovery button.
ASPx<dx:GridViewCommandColumn ShowNewButtonInHeader="true" ShowDeleteButton="true" ShowRecoverButton="true">
<CustomButtons>
<dx:GridViewCommandColumnCustomButton ID="customRecover" Text="Recover"></dx:GridViewCommandColumnCustomButton>
</CustomButtons>
</dx:GridViewCommandColumn>
Add custom CSS classes to control the custom button's visibility based on a condition and hide the default Recovery button.
ASPx<Styles>
<CommandColumnItem CssClass="commandCell"></CommandColumnItem>
<BatchEditDeletedRow CssClass="deletedRow"></BatchEditDeletedRow>
</Styles>
CSS.deletedRow a[data-args*="customRecover"].commandCell {
display: inline !important;
}
a[data-args*="customRecover"].commandCell {
display: none;
}
a[data-args*="Recover"].commandCell {
display: none;
}
Handle the grid's client-side CustomButtonClick event to restore the deleted row and recalculate the total summary.
JavaScriptfunction OnCustomButtonClick(s, e) {
if (e.buttonID == 'customRecover') {
s.batchEditApi.ResetChanges(e.visibleIndex);
var value = s.batchEditApi.GetCellValue(e.visibleIndex, "C2");
labelSum.SetValue((parseFloat(labelSum.GetValue()) + value).toFixed(1));
}
}
Files to Review
- Default.aspx (VB: Default.aspx)
- Default.aspx.cs (VB: Default.aspx.vb)
Documentation
More Examples
- Grid View for ASP.NET Web Forms - How to update total summaries on the client in batch edit mode
- Grid View for ASP.NET Web Forms - How to calculate values dynamically in batch edit mode
- Grid View for ASP.NET Web Forms - How to calculate values and update total summaries dynamically in batch edit mode
- Grid View for ASP.NET MVC - How to update total summaries on the client in batch edit mode
Example Code
ASPx<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="DevExpress.Web.v16.2, Version=16.2.17.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.Web" TagPrefix="dx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>ASPxGridView - Batch Editing - How to update total summaries on the client side when BatchEditSettings.HighlightDeletedRows = true</title>
<style type="text/css">
.deletedRow a[data-args*="customRecover"].commandCell {
display: inline !important;
}
a[data-args*="customRecover"].commandCell {
display: none;
}
a[data-args*="Recover"].commandCell {
display: none;
}
</style>
<script type="text/javascript">
function OnBatchEditEndEditing(s, e) {
CalculateSummary(s, e.rowValues, e.visibleIndex, false);
}
function CalculateSummary(grid, rowValues, visibleIndex, isDeleting) {
var originalValue = grid.batchEditApi.GetCellValue(visibleIndex, "C2");
var newValue = rowValues[(grid.GetColumnByField("C2").index)].value;
var dif = isDeleting ? -newValue : newValue - originalValue;
labelSum.SetValue((parseFloat(labelSum.GetValue()) + dif).toFixed(1));
}
function OnBatchEditRowDeleting(s, e) {
CalculateSummary(s, e.rowValues, e.visibleIndex, true);
}
function OnChangesCanceling(s, e) {
if (s.batchEditApi.HasChanges())
setTimeout(function () {
s.Refresh();
}, 0);
}
function OnCustomButtonClick(s, e) {
if (e.buttonID == 'customRecover') {
s.batchEditApi.ResetChanges(e.visibleIndex);
var value = s.batchEditApi.GetCellValue(e.visibleIndex, "C2");
labelSum.SetValue((parseFloat(labelSum.GetValue()) + value).toFixed(1));
}
}
</script>
</head>
<body>
<form id="frmMain" runat="server">
<dx:ASPxGridView ID="Grid" runat="server" KeyFieldName="ID" OnBatchUpdate="Grid_BatchUpdate"
OnRowInserting="Grid_RowInserting" OnRowUpdating="Grid_RowUpdating" OnRowDeleting="Grid_RowDeleting"
ClientInstanceName="gridView" Theme="Office2010Silver">
<Styles>
<CommandColumnItem CssClass="commandCell"></CommandColumnItem>
<BatchEditDeletedRow CssClass="deletedRow"></BatchEditDeletedRow>
</Styles>
<Columns>
<dx:GridViewCommandColumn ShowNewButtonInHeader="true" ShowDeleteButton="true" ShowRecoverButton="true">
<CustomButtons>
<dx:GridViewCommandColumnCustomButton ID="customRecover" Text="Recover"></dx:GridViewCommandColumnCustomButton>
</CustomButtons>
</dx:GridViewCommandColumn>
<dx:GridViewDataColumn FieldName="C1" />
<dx:GridViewDataSpinEditColumn Width="100" FieldName="C2">
<FooterTemplate>
Sum =
<dx:ASPxLabel ID="ASPxLabel1" runat="server" ClientInstanceName="labelSum" Text='<%# GetTotalSummaryValue() %>'>
</dx:ASPxLabel>
</FooterTemplate>
</dx:GridViewDataSpinEditColumn>
<dx:GridViewDataTextColumn FieldName="C3" />
<dx:GridViewDataCheckColumn FieldName="C4" />
<dx:GridViewDataDateColumn FieldName="C5" />
</Columns>
<SettingsEditing Mode="Batch" />
<Settings ShowFooter="true" />
<TotalSummary>
<dx:ASPxSummaryItem SummaryType="Sum" FieldName="C2" Tag="C2_Sum" />
</TotalSummary>
<ClientSideEvents BatchEditChangesCanceling="OnChangesCanceling" BatchEditRowDeleting="OnBatchEditRowDeleting"
BatchEditEndEditing="OnBatchEditEndEditing" CustomButtonClick="OnCustomButtonClick" />
</dx:ASPxGridView>
</form>
</body>
</html>
C#using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using DevExpress.Web.Data;
using DevExpress.Web;
public partial class _Default : System.Web.UI.Page {
protected List<GridDataItem> GridData {
get {
var key = "34FAA431-CF79-4869-9488-93F6AAE81263";
if(!IsPostBack || Session[key] == null)
Session[key] = Enumerable.Range(0, 100).Select(i => new GridDataItem {
ID = i,
C1 = i % 2,
C2 = i * 0.5 % 3,
C3 = "C3 " + i,
C4 = i % 2 == 0,
C5 = new DateTime(2013 + i, 12, 16)
}).ToList();
return (List<GridDataItem>)Session[key];
}
}
protected void Page_Load(object sender, EventArgs e) {
Grid.DataSource = GridData;
Grid.DataBind();
}
protected void Grid_RowInserting(object sender, ASPxDataInsertingEventArgs e) {
InsertNewItem(e.NewValues);
CancelEditing(e);
}
protected void Grid_RowUpdating(object sender, ASPxDataUpdatingEventArgs e) {
UpdateItem(e.Keys, e.NewValues);
CancelEditing(e);
}
protected void Grid_RowDeleting(object sender, ASPxDataDeletingEventArgs e) {
DeleteItem(e.Keys, e.Values);
CancelEditing(e);
}
protected void Grid_BatchUpdate(object sender, ASPxDataBatchUpdateEventArgs e) {
foreach(var args in e.InsertValues)
InsertNewItem(args.NewValues);
foreach(var args in e.UpdateValues)
UpdateItem(args.Keys, args.NewValues);
foreach(var args in e.DeleteValues)
DeleteItem(args.Keys, args.Values);
e.Handled = true;
}
protected GridDataItem InsertNewItem(OrderedDictionary newValues) {
var item = new GridDataItem() { ID = GridData.Count };
LoadNewValues(item, newValues);
GridData.Add(item);
return item;
}
protected GridDataItem UpdateItem(OrderedDictionary keys, OrderedDictionary newValues) {
var id = Convert.ToInt32(keys["ID"]);
var item = GridData.First(i => i.ID == id);
LoadNewValues(item, newValues);
return item;
}
protected GridDataItem DeleteItem(OrderedDictionary keys, OrderedDictionary values) {
var id = Convert.ToInt32(keys["ID"]);
var item = GridData.First(i => i.ID == id);
GridData.Remove(item);
return item;
}
protected void LoadNewValues(GridDataItem item, OrderedDictionary values) {
item.C1 = Convert.ToInt32(values["C1"]);
item.C2 = Convert.ToDouble(values["C2"]);
item.C3 = Convert.ToString(values["C3"]);
item.C4 = Convert.ToBoolean(values["C4"]);
item.C5 = Convert.ToDateTime(values["C5"]);
}
protected void CancelEditing(CancelEventArgs e) {
e.Cancel = true;
Grid.CancelEdit();
}
public class GridDataItem {
public int ID { get; set; }
public int C1 { get; set; }
public double C2 { get; set; }
public string C3 { get; set; }
public bool C4 { get; set; }
public DateTime C5 { get; set; }
}
protected object GetTotalSummaryValue() {
ASPxSummaryItem summaryItem = Grid.TotalSummary.First(i => i.Tag == "C2_Sum");
return Grid.GetTotalSummaryValue(summaryItem);
}
}