Data Manipulation in Windows Forms DataGrid (SfDataGrid)
7 Mar 202321 minutes to read
SfDataGrid listens and responds to the manipulation operations such as add, delete and data update (property change) at runtime. DataGrid refresh the sorting, filtering, grouping and summaries based on SfDataGrid.LiveDataUpdateMode property.
this.sfDataGrid1.LiveDataUpdateMode = LiveDataUpdateMode.AllowDataShaping;
Me.sfDataGrid1.LiveDataUpdateMode = LiveDataUpdateMode.AllowDataShaping
LiveDataUpdateMode
LiveDataUpdateMode – Default
Grid operations/ Data Manipulation operations |
Add |
Remove / delete |
Property change |
Sorting |
Record added at last | Updated | Sort order not updated |
Grouping |
Updated | Updated | Groups not refreshed based on change |
Filtering |
Updated | Updated | Filter not refreshed based on change |
Summaries |
Not updated | Not updated | Not updated |
LiveDataUpdateMode – AllowSummaryUpdate
Grid operations/ Data Manipulation operations |
Add |
Remove / delete |
Property change |
Sorting |
Record added at last | Updated | Sort order not updated |
Grouping |
Updated | Updated | Groups not refreshed based on change |
Filtering |
Updated | Updated | Filter not refreshed based on change |
Summaries |
Updated | Updated | Updated |
LiveDataUpdateMode – AllowDataShaping
Grid operations/ Data Manipulation operations |
Add |
Remove / delete |
Property change |
Sorting |
Updated | Updated | Updated |
Grouping |
Updated | Updated | Updated |
Filtering |
Updated | Updated | Updated |
Summaries |
Updated | Updated | Updated |
Limitations
-
AllowDataShaping
andAllowSummaryUpdate
is not supported when you are binding with dynamic data objects. - Complex and indexer properties doesn’t support
LiveDataUpdateMode
-AllowDataShaping
andAllowSummaryUpdate
.
AddNewRow
SfDataGrid provides built-in row (called AddNewRow) to add new records to underlying collection. AddNewRow can be enabled by specifying the position where it should be displayed by setting SfDataGrid.AddNewRowPosition property.
When start editing in AddNewRow, the SfDataGrid control creates an instance for the underlying data object and adds it to underlying collection when editing completed.
NOTE
The underlying data object must be defined with default constructor. Otherwise, create instance of data object by handling AddNewRowInitiating event.
sfDataGrid.AddNewRowPosition = RowPosition.Top;
sfDataGrid.AddNewRowPosition = RowPosition.Top
Placing AddNewRow at Various Positions
SfDataGrid allows to add the AddNewRow at either top or fixed top or bottom or fixed bottom by setting the AddNewRowPosition
property.
sfDataGrid.AddNewRowPosition = RowPosition.FixedBottom;
sfDataGrid.AddNewRowPosition = RowPosition.FixedBottom
SfDataGrid allows to check whether the specified row index is AddNewRow index, by using SfDataGrid.IsAddNewRowIndex helper method.
sfDataGrid.IsAddNewRowIndex(1);
sfDataGrid.IsAddNewRowIndex(1)
Customize the Newly Added Row Position
SfDataGrid adds new data item from AddNewRow at the end of collection. When data operations (sorting, grouping) performed, the new item added based on data operations. The newly added data item position can be customized by setting NewItemPlaceholderPosition property.
sfDataGrid.NewItemPlaceholderPosition = Syncfusion.Data.NewItemPlaceholderPosition.AtBeginning;
sfDataGrid.NewItemPlaceholderPosition = Syncfusion.Data.NewItemPlaceholderPosition.AtBeginning
Initializing Default Values for AddNewRow
SfDataGrid allows to set the default values for AddNewRow while initiating, through AddNewRowInitiatingEventArgs.NewObject property in AddNewRowInitiating
event.
this.sfDataGrid.AddNewRowInitiating += dataGrid_AddNewRowInitiating;
void dataGrid_AddNewRowInitiating(object sender, AddNewRowInitiatingEventArgs args)
{
var data = args.NewObject as OrderInfo;
data.OrderID = 101;
}
AddHandler sfDataGrid.AddNewRowInitiating, AddressOf dataGrid_AddNewRowInitiating
Private Sub dataGrid_AddNewRowInitiating(ByVal sender As Object, ByVal args As AddNewRowInitiatingEventArgs)
Dim data = TryCast(args.NewObject, OrderInfo)
data.OrderID = 101
End Sub
Validating the AddNewRow
The data in AddNewRow can validate like other data rows through built-in validation or custom validation. Here, AddNewRow is validated using RowValidating event by setting RowValidatingEventArgs.IsValid to false which doesn’t allow users to commit the AddNewRow until the validation gets succeeded.
this.sfDataGrid.RowValidating += dataGrid_RowValidating;
void dataGrid_RowValidating(object sender, RowValidatingEventArgs args)
{
if (this.sfDataGrid.IsAddNewRowIndex(args.DataRow.RowIndex))
{
var data = args.DataRow.RowData as OrderInfo;
if (data.OrderID < 10000)
{
args.IsValid = false;
args.ErrorMessage = "OrderID should greater than 10000.";
}
}
}
AddHandler sfDataGrid.RowValidating, AddressOf dataGrid_RowValidating
Private Sub dataGrid_RowValidating(ByVal sender As Object, ByVal args As RowValidatingEventArgs)
If Me.sfDataGrid.IsAddNewRowIndex(args.DataRow.RowIndex) Then
Dim data = TryCast(args.DataRow.RowData, OrderInfo)
If data.OrderID < 10000 Then
args.IsValid = False
args.ErrorMessage = "OrderID should greater than 10000."
End If
End If
End Sub
Similarly, the cells can validate in AddNewRow by using theCurrentCellValidating event.
Prevent adding empty records
Adding empty record using AddNewRow can be prevented by setting the RowValidatingEventArgs.IsValid property to false in RowValidating event.
sfDataGrid.RowValidating += sfDataGrid_RowValidating;
void sfDataGrid_RowValidating(object sender, Syncfusion.WinForms.DataGrid.Events.RowValidatingEventArgs e)
{
var data = e.DataRow.RowData as OrderInfo;
if (string.IsNullOrEmpty(data.CustomerID) || string.IsNullOrEmpty(data.ProductName) || string.IsNullOrEmpty(data.ShipCountry))
{
e.ErrorMessage = "Records cannot be empty";
e.IsValid = false;
}
}
AddHandler sfDataGrid.RowValidating, AddressOf sfDataGrid_RowValidating
Private Sub sfDataGrid_RowValidating(ByVal sender As Object, ByVal e As Syncfusion.WinForms.DataGrid.Events.RowValidatingEventArgs)
Dim data = TryCast(e.DataRow.RowData, OrderInfo)
If String.IsNullOrEmpty(data.CustomerID) OrElse String.IsNullOrEmpty(data.ProductName) OrElse String.IsNullOrEmpty(data.ShipCountry) Then
e.ErrorMessage = "Records cannot be empty"
e.IsValid = False
End If
End Sub
Update cell values based on selected value in the GridComboBoxCell
By default, changes made in the current record of add new row cell will be immediately reflected in the view. The following code shows how to change other cell value based on the selected value in the combo box cell of AddNewRow by using the CellComboBoxSelectionChanged event.
this.sfDataGrid.CellComboBoxSelectionChanged += OnSfDataGridCellComboBoxSelectionChanged;
private void OnSfDataGridCellComboBoxSelectionChanged(object sender, Syncfusion.WinForms.DataGrid.Events.CellComboBoxSelectionChangedEventArgs e)
{
if (e.GridColumn.MappingName == "ShipCityID")
{
var shipCityDetails = e.SelectedItem as ShipCityDetails;
var row = e.Record as OrderDetails;
row.OrderID = shipCityDetails.ShipCityID;
if (e.RowIndex == this.sfDataGrid.GetAddNewRowIndex())
this.sfDataGrid.TableControl.Invalidate(this.sfDataGrid.TableControl.GetRowRectangle(this.sfDataGrid.GetAddNewRowIndex(), false));
}
}
AddHandler CellComboBoxSelectionChanged, AddressOf OnSfDataGridCellComboBoxSelectionChanged
Private Sub SfDataGridCellComboBoxSelectionChanged(ByVal sender As Object, ByVal e As Syncfusion.WinForms.DataGrid.Events.CellComboBoxSelectionChangedEventArgs)
If e.GridColumn.MappingName = "ShipCityID" Then
Dim shipCityDetails = TryCast(e.SelectedItem, ShipCityDetails)
Dim row = TryCast(e.Record, OrderDetails)
row.OrderID = shipCityDetails.ShipCityID
If e.RowIndex = Me.sfDataGrid.GetAddNewRowIndex() Then
Me.sfDataGrid.TableControl.Invalidate(Me.sfDataGrid.TableControl.GetRowRectangle(Me.sfDataGrid.GetAddNewRowIndex(), False))
End If
End If
End Sub
Customizing AddNewRow text programmatically
You can change the add new row text programmatically using the sfDataGrid.AddNewRowText property.
this.sfDataGrid.AddNewRowText = "Click to add new row";
Me.sfDataGrid.AddNewRowText = "Click to add new row"
Customizing AddNewRow Text using Default Resource File
SfDataGrid allows to customize the watermark text of AddNewRow by changing value of AddNewRowText in Resource Designer. To customize the AddNewRowText, add the default Syncfusion.SfDataGrid.WinForms.resx
file in Resources folder and then customize the value of AddNewRowText.
Appearance
The appearance of the AddNewRow can be customized by setting the AddNewRowStyle.
this.sfDataGrid.Style.AddNewRowStyle.BackColor = Color.DarkCyan;
this.sfDataGrid.Style.AddNewRowStyle.TextColor = Color.White;
Me.sfDataGrid.Style.AddNewRowStyle.BackColor = Color.DarkCyan
Me.sfDataGrid.Style.AddNewRowStyle.TextColor = Color.White
Adding a new row programmatically
Programmatically, a new row can be added to the SfDataGrid.
OrderInfoCollection orderInfoCollection = new OrderInfoCollection();
sfDataGrid.DataSource = orderInfoCollection.OrdersListDetails;
OrderInfo orderInfo = new OrderInfo() { OrderID = 10111, CustomerID = "FRANS", ProductName = "Alice Mutton", Quantity = 55, UnitPrice = 90, ContactNumber = 999789845, ShipCountry = "Brazil" };
orderInfoCollection.OrdersListDetails.Add(orderInfo);
Dim orderInfoCollection As New OrderInfoCollection()
sfDataGrid.DataSource = orderInfoCollection.OrdersListDetails
Dim orderInfo As New OrderInfo() With {.OrderID = 10111, .CustomerID = "FRANS", .ProductName = "Alice Mutton", .Quantity = 55, .UnitPrice = 90, .ContactNumber = 999789845, .ShipCountry = "Brazil"}
orderInfoCollection.OrdersListDetails.Add(orderInfo)
To add a new row when DataGrid bound to ObservableCollection
You can add the new row programmatically from a ObservableCollection
to the SfDataGrid by creating a new row in the SfDataGrid.View
and set required value for that row.
var orderData = this.sfDataGrid.DataSource;
if (orderData == null || this.sfDataGrid.View == null)
return;
// Creates a new row.
var orderInfo = sfDataGrid.View.AddNew() as OrderInfo;
// Commits the newly created row.
sfDataGrid.View.CommitNew();
// Initialize the values of first row to the newly added row.
orderInfo.OrderID = 1001;
orderInfo.Quantity = 13;
orderInfo.OrderDate = new System.DateTime(2020, 3, 2);
orderInfo.CustomerID = "FRANS";
orderInfo.ContactNumber = 909093455;
Dim orderData = Me.sfDataGrid.DataSource
If orderData Is Nothing OrElse Me.sfDataGrid.View Is Nothing Then
Return
End If
' Creates a new row.
Dim orderInfo = TryCast(sfDataGrid.View.AddNew(), OrderInfo)
' Commits the newly created row.
sfDataGrid.View.CommitNew()
' Initialize the values of first row to the newly added row.
orderInfo.OrderID = 1001
orderInfo.Quantity = 13
orderInfo.OrderDate = New System.DateTime(2020, 3, 2)
orderInfo.CustomerID = "FRANS"
orderInfo.ContactNumber = 909093455
To add a new row when DataGrid bound to DataTable
You can add the new row programmatically from a DataTable
to the SfDataGrid by creating a new row in the SfDataGrid.View
and set required value for that row.
DataTable gridDataTable = this.sfDataGrid.DataSource as DataTable;
if (gridDataTable == null || this.sfDataGrid.View == null)
return;
// Creates a new row.
System.Data.DataRow addNewRow = sfDataGrid.View.AddNew() as System.Data.DataRow;
// Commits the newly created row.
sfDataGrid.View.CommitNew();
// Initialize the values of first row to the newly added row.
addNewRow.SetField(0, gridDataTable.Rows[0][0]);
addNewRow.SetField(1, gridDataTable.Rows[0][1]);
addNewRow.SetField(2, gridDataTable.Rows[0][2]);
addNewRow.SetField(3, gridDataTable.Rows[0][3]);
addNewRow.SetField(4, gridDataTable.Rows[0][4]);
Dim gridDataTable As DataTable = TryCast(Me.sfDataGrid.DataSource, DataTable)
If gridDataTable Is Nothing OrElse Me.sfDataGrid.View Is Nothing Then
Return
End If
' Creates a new row.
Dim addNewRow As System.Data.DataRow = TryCast(sfDataGrid.View.AddNew(), System.Data.DataRow)
' Commits the newly created row.
sfDataGrid.View.CommitNew()
' Initialize the values of first row to the newly added row.
addNewRow.SetField(0, gridDataTable.Rows(0)(0))
addNewRow.SetField(1, gridDataTable.Rows(0)(1))
addNewRow.SetField(2, gridDataTable.Rows(0)(2))
addNewRow.SetField(3, gridDataTable.Rows(0)(3))
addNewRow.SetField(4, gridDataTable.Rows(0)(4))
You can download sample here.
AddNewRow support in Master-Details view
You can enable the AddNewRow in DetailsViewDataGrid using the GridViewDefinition.DataGrid property.
Enabling AddNewRow when manually defining relations
For manually defined relations, the AddNewRowPosition
can be directly initialized to the datagrid of the defined GridViewDefinition
.
GridViewDefinition firstLevelGridViewDefinition = new GridViewDefinition();
firstLevelGridViewDefinition.RelationalColumn = "OrderDetails";
SfDataGrid firstLevelNestedGrid = new SfDataGrid();
firstLevelNestedGrid.AddNewRowPosition = RowPosition.Top;
firstLevelGridViewDefinition.DataGrid = firstLevelNestedGrid;
sfDataGrid.DetailsViewDefinitions.Add(firstLevelGridViewDefinition);
Dim firstLevelGridViewDefinition As New GridViewDefinition()
firstLevelGridViewDefinition.RelationalColumn = "OrderDetails"
Dim firstLevelNestedGrid As New SfDataGrid()
firstLevelNestedGrid.AddNewRowPosition = RowPosition.Top
firstLevelGridViewDefinition.DataGrid = firstLevelNestedGrid
sfDataGrid.DetailsViewDefinitions.Add(firstLevelGridViewDefinition)
Enabling AddNewRow when auto-generating relations
When relation is auto-generated, you can initialize the AddNewRowPosition
for GridViewDefinition.DataGrid
in the AutoGeneratingRelations event.
this.sfDataGrid1.AutoGeneratingRelations += sfDataGrid1_AutoGeneratingRelations;
private void sfDataGrid1_AutoGeneratingRelations(object sender, Syncfusion.WinForms.DataGrid.Events.AutoGeneratingRelationsEventArgs e)
{
e.GridViewDefinition.DataGrid.AddNewRowPosition = RowPosition.Top;
}
AddHandler sfDataGrid1. AutoGeneratingRelations, AddressOf SfDataGrid_AutoGeneratingRelations
Private Sub SfDataGrid_AutoGeneratingRelations(ByVal sender As Object, ByVal e As AutoGeneratingRelationsEventArgs)
e.GridViewDefinition.DataGrid.AddNewRowPosition = RowPosition.Top;
End Sub
Delete Row
SfDataGrid provides built-in support to delete the selected records in user interface (UI) by pressing Delete key. The deleting support can be enabled by setting the SfDataGrid.AllowDeleting property to true. AllowDeleting
is only supported when SelectionUnit
is Row
.
this.sfDataGrid.AllowDeleting = true;
Me.sfDataGrid.AllowDeleting = True
Delete the Selected Records through Code
The selected records can be deleted by using the DeleteSelectedRecords method in SfDataGrid. This method is only supported when SelectionUnit
is Row
.
this.sfDataGrid.DeleteSelectedRecords();
Me.sfDataGrid.DeleteSelectedRecords()
Customizing the Delete Operations
Conditionally Deleting Records
RecordDeleting event occurs when the record is being deleted from SfDataGrid. The record deletion can be cancel by using the RecordDeletingEventArgs.Cancel of RecordDeleting
event. The certain records can be skipped when deleting more than one record by removing items from RecordDeletingEventArgs.Items.
this.sfDataGrid.RecordDeleting += dataGrid_RecordDeleting;
void dataGrid_RecordDeleting(object sender, RecordDeletingEventArgs args)
{
foreach (var item in args.Items)
{
if ((item as OrderInfo).OrderID == 10001)
{
args.Cancel = true;
}
}
}
AddHandler sfDataGrid.RecordDeleting, AddressOf dataGrid_RecordDeleting
Private Sub dataGrid_RecordDeleting(ByVal sender As Object, ByVal args As RecordDeletingEventArgs)
For Each item In args.Items
If (TryCast(item, OrderInfo)).OrderID = 10001 Then
args.Cancel = True
End If
Next item
End Sub
Handling Selection after Deleting the Record
RecordDeleted event occurs after the record is deleted. The selection can be changed after remove the records through SelectedIndex property of RecordDeleted
event.
this.sfDataGrid.RecordDeleted += dataGrid_RecordDeleted;
void dataGrid_RecordDeleted(object sender, RecordDeletedEventArgs args)
{
args.SelectedIndex = -1;
}
AddHandler sfDataGrid.RecordDeleted, AddressOf dataGrid_RecordDeleted
Private Sub dataGrid_RecordDeleted(ByVal sender As Object, ByVal args As RecordDeletedEventArgs)
args.SelectedIndex = -1
End Sub
Deleting a row programmatically
Programmatically, a row can be deleted from the SfDataGrid. The following code shows how to delete particular row based on the values.
var orderInfo = orderInfoCollection.OrdersListDetails.FirstOrDefault(order => order.OrderID == 10000);
orderInfoCollection.OrdersListDetails.Remove(orderInfo);
Dim orderInfo = orderInfoCollection.OrdersListDetails.FirstOrDefault(Function(order) order.OrderID = 10000)
orderInfoCollection.OrdersListDetails.Remove(orderInfo)
The following code shows how to delete a row using the index of the row.
orderInfoCollection.OrdersListDetails.RemoveAt(1);
orderInfoCollection.OrdersListDetails.RemoveAt(1)