In order to perform various actions over the GridDataBoundGrid control, you first need to locate the row that contains the data you are going to work with. This topic describes two approaches that you can use to search for the desired grid record, and compares them.
To perform these actions, TestComplete should have access to internal objects, properties and methods of the GridDataBoundGrid control. For this purpose, the .NET Application Support plugin must be installed and enabled. When testing Syncfusion GridDataBoundGrid controls, use specific methods and properties of the corresponding |
Searching Within the Grid’s Dataset
If the grid’s data is bound to an external dataset, you can search for the desired record within the dataset rather than within the grid itself. Searching within the grid’s data source is a universal approach that is free from the grid’s user interface limitations.
To obtain the grid’s underlying dataset, use the DataSource
property of the grid control. Since the GridDataBoundGrid control can be bound to various source types, the object returned by the DataSource
property may have a different structure in different applications. To explore the dataset object, find the grid’s DataSource
property in the Object Browser panel and click the ellipsis button on the right of the property cell -- you will see the properties and methods of the object returned by this property. Digging further, you will be able to determine the exact “path” to the table object containing the data and the methods that can be used to search within this table.
Let’s illustrate this approach by the example of the grid bound to the ADO.NET dataset. You can search in the dataset using the Find
or FindRows
method of a .NET DataView
object that represents a view of the grid data. To obtain the DataView
object, you can use this statement:
GridObj.BindingContext.Item_2( GridObj.DataSource, GridObj.DataMember ).List
To search within the DataView
object, you can use the Find
or FindRows
methods. The difference between these methods is that Find
returns the index of the first found row that matches the search criteria, whereas FindRows
returns the array of objects corresponding to all matching rows. The parameter of both methods is the value that is sought for (integer, double, string, date or any other). If rows that match the search criteria are not found, Find
returns -1 and FindRows
returns an empty array (with no elements).
Searching a DataView
object implies the following steps:
- Specify the name of the data table field in which the search is performed in the
DataView.Sort
property. - To perform a case-sensitive search, set the
DataView.Table.CaseSensitive
property to True. - Call the
Find
orFindRows
method and specify the sought-for value as a parameter. Note that to search for a complex value (such asSystem.DateTime
), you need to create an instance of the corresponding .NET class. For more information on how you can do this, see Calling Functions From .NET Assemblies.
Below is an example that demonstrates how you can search for a specific record in the grid’s dataset.
Example
JavaScript, JScript
function Main ()
{
var p, Grid, RowIndex;
// Obtain the application process and the grid object
p = Sys.Process ("DataBoundSortByDisplayMember");
Grid = p.WinFormsObject("Form1").WinFormsObject("gridDataBoundGrid1");
// Locate the row by cell text
RowIndex = FindRow (Grid, "ProductID", 43);
if (RowIndex != -1)
ClickCell (Grid, RowIndex, "ProductID")
else
Log.Error ("Row was not found.");
}
function FindRow (Grid, ColumnId, Value)
{
var DataView, FieldIndex, DataRowIndex;
// Get the grid's DataView
DataView = Grid.BindingContext.Item_2(Grid.DataSource, Grid.DataMember).List;
// Sort the DataView by the specified column
if (aqObject.GetVarType (ColumnId) == varOleStr)
FieldIndex = Grid.Binder.NameToField (ColumnId)
else
FieldIndex = Grid.Binder.ColIndexToField (ColumnId);
DataView.Sort = DataView.Table.Columns.Item(FieldIndex).ColumnName;
// Find data row containing the specified value
DataRowIndex = DataView.Find (Value);
// Get the grid row index corresponding to the found data row
return Grid.Binder.ListManagerPositionToRowIndex (DataRowIndex);
}
function ClickCell (Grid, RowIndex, ColumnId)
{
var ColIndex, rect;
// Convert the column's identifier to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId);
// Make cell visible
Grid.ScrollCellInView_3 (RowIndex, ColIndex);
// Get the cell coordinates
rect = Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell(RowIndex, ColIndex));
Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2);
}
function GetColIndexById (Grid, ColumnId)
{
if (aqObject.GetVarType(ColumnId) == varOleStr)
return Grid.NameToColIndex(ColumnId)
else
return ColumnId;
}
Python
def Main ():
# Obtain the application process and the grid object
p = Sys.Process ("DataBoundSortByDisplayMember")
Grid = p.WinFormsObject("Form1").WinFormsObject("gridDataBoundGrid1")
# Locate the row by cell text
RowIndex = FindRow (Grid, "ProductID", 43)
if (RowIndex != -1):
ClickCell (Grid, RowIndex, "ProductID")
else:
Log.Error ("Row was not found.")
def FindRow (Grid, ColumnId, Value):
# Get the grid's DataView
DataView = Grid.BindingContext.Item_2(Grid.DataSource, Grid.DataMember).List
# Sort the DataView by the specified column
if (aqObject.GetVarType (ColumnId) == varOleStr):
FieldIndex = Grid.Binder.NameToField (ColumnId)
else:
FieldIndex = Grid.Binder.ColIndexToField (ColumnId)
DataView.Sort = DataView.Table.Columns.Item[FieldIndex].ColumnName
# Find data row containing the specified value
DataRowIndex = DataView.Find (Value)
# Get the grid row index corresponding to the found data row
return Grid.Binder.ListManagerPositionToRowIndex (DataRowIndex)
def ClickCell (Grid, RowIndex, ColumnId):
# Convert the column's identifier to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId)
# Make cell visible
Grid.ScrollCellInView_3 (RowIndex, ColIndex)
# Get the cell coordinates
rect = Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell[RowIndex, ColIndex])
Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2)
def GetColIndexById (Grid, ColumnId):
if (aqObject.GetVarType(ColumnId) == varOleStr):
return Grid.NameToColIndex(ColumnId)
else:
return ColumnId
VBScript
Sub Main
Dim p, Grid, RowIndex
' Obtain the application process and the grid object
Set p = Sys.Process ("DataBoundSortByDisplayMember")
Set Grid = p.WinFormsObject("Form1").WinFormsObject("gridDataBoundGrid1")
' Locate the row by cell text
RowIndex = FindRow (Grid, "ProductID", 43)
If RowIndex <> -1 Then
Call ClickCell (Grid, RowIndex, "ProductID")
Else
Call Log.Error ("Row was not found.")
End If
End Sub
Function FindRow (Grid, ColumnId, Value)
Dim DataView, FieldIndex, DataRowIndex
' Get the grid's DataView
Set DataView = Grid.BindingContext.Item_2(Grid.DataSource, Grid.DataMember).List
' Sort the DataView by the specified column
If aqObject.GetVarType (ColumnId) = varOleStr Then
FieldIndex = Grid.Binder.NameToField (ColumnId)
Else
FieldIndex = Grid.Binder.ColIndexToField (ColumnId)
End If
Set DataView.Sort = DataView.Table.Columns.Item(FieldIndex).ColumnName
' Find data row containing the specified value
DataRowIndex = DataView.Find (Value)
' Get the grid row index corresponding to the found data row
FindRow = Grid.Binder.ListManagerPositionToRowIndex (DataRowIndex)
End Function
Sub ClickCell (Grid, RowIndex, ColumnId)
Dim ColIndex, rect
' Convert the column's identifier to its index
ColIndex = GetColIndexById (Grid, ColumnId)
' Make cell visible
Call Grid.ScrollCellInView_3 (RowIndex, ColIndex)
' Get the cell coordinates
Set rect = Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell(RowIndex, ColIndex))
Call Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2)
End Sub
Function GetColIndexById (Grid, ColumnId)
If aqObject.GetVarType(ColumnId) = varOleStr Then
GetColIndexById = Grid.NameToColIndex(ColumnId)
Else
GetColIndexById = ColumnId
End If
End Function
DelphiScript
function FindRow (Grid, ColumnId, Value); forward;
procedure ClickCell (Grid, RowIndex, ColumnId); forward;
function GetColIndexById (Grid, ColumnId); forward;
procedure Main;
var p, Grid, RowIndex : OleVariant;
begin
// Obtain the application process and the grid object
p := Sys.Process ('DataBoundSortByDisplayMember');
Grid := p.WinFormsObject('Form1').WinFormsObject('gridDataBoundGrid1');
// Locate the row by cell text
RowIndex := FindRow (Grid, 'ProductID', 43);
if RowIndex <> -1 then
ClickCell (Grid, RowIndex, 'ProductID')
else
Log.Error ('Row was not found.');
end;
function FindRow (Grid, ColumnId, Value);
var DataView, FieldIndex, DataRowIndex : OleVariant;
begin
// Get the grid's DataView
DataView := Grid.BindingContext.Item_2(Grid.DataSource, Grid.DataMember).List;
// Sort the DataView by the specified column
if aqObject.GetVarType (ColumnId) = varOleStr then
FieldIndex := Grid.Binder.NameToField (ColumnId)
else
FieldIndex := Grid.Binder.ColIndexToField (ColumnId);
DataView.Sort := DataView.Table.Columns.Item(FieldIndex).ColumnName;
// Find data row containing the specified value
DataRowIndex := DataView.Find (Value);
// Get the grid row index corresponding to the found data row
Result := Grid.Binder.ListManagerPositionToRowIndex (DataRowIndex);
end;
procedure ClickCell (Grid, RowIndex, ColumnId);
var ColIndex, rect : OleVariant;
begin
// Convert the column's identifier to its index
ColIndex := GetColIndexById (Grid, ColumnId);
// Make cell visible
Grid.ScrollCellInView_3 (RowIndex, ColIndex);
// Get the cell coordinates
rect := Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell(RowIndex, ColIndex));
Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2);
end;
function GetColIndexById (Grid, ColumnId);
begin
if aqObject.GetVarType(ColumnId) = varOleStr then
Result := Grid.NameToColIndex(ColumnId)
else
Result := ColumnId;
end;
C++Script, C#Script
function Main ()
{
var p, Grid, RowIndex;
// Obtain the application process and the grid object
p = Sys["Process"]("DataBoundSortByDisplayMember");
Grid = p["WinFormsObject"]("Form1")["WinFormsObject"]("gridDataBoundGrid1");
// Locate the row by cell text
RowIndex = FindRow (Grid, "ProductID", 43);
if (RowIndex != -1)
ClickCell (Grid, RowIndex, "ProductID")
else
Log["Error"]("Row was not found.");
}
function FindRow (Grid, ColumnId, Value)
{
var DataView, FieldIndex, DataRowIndex;
// Get the grid's DataView
DataView = Grid["BindingContext"]["Item_2"](Grid["DataSource"], Grid["DataMember"])["List"];
// Sort the DataView by the specified column
if (aqObject["GetVarType"] (ColumnId) == varOleStr)
FieldIndex = Grid["Binder"]["NameToField"](ColumnId)
else
FieldIndex = Grid["Binder"]["ColIndexToField"](ColumnId);
DataView["Sort"] = DataView["Table"]["Columns"]["Item"](FieldIndex)["ColumnName"];
// Find data row containing the specified value
DataRowIndex = DataView["Find"](Value);
// Get the grid row index corresponding to the found data row
return Grid["Binder"]["ListManagerPositionToRowIndex"](DataRowIndex);
}
function ClickCell (Grid, RowIndex, ColumnId)
{
var ColIndex, rect;
// Convert the column's identifier to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId);
// Make cell visible
Grid["ScrollCellInView_3"](RowIndex, ColIndex);
// Get the cell coordinates
rect = Grid["RangeInfoToRectangle"](Grid["GridCellsRange"]["Cell"](RowIndex, ColIndex));
Grid["Click"](rect["X"] + rect["Width"]/2, rect["Y"] + rect["Height"]/2);
}
function GetColIndexById (Grid, ColumnId)
{
if (aqObject["GetVarType"](ColumnId) == varOleStr)
return Grid["NameToColIndex"](ColumnId)
else
return ColumnId;
}
Note: | The Find and FindRows methods have overloaded versions that let you search for a record by values used in multiple columns. TestComplete extends the name of these methods with indexes, for example, Find_2 and FindRows_2 . For more information on using these methods and searching within the DataView object, see the Finding Rows article in the MSDN library. |
Searching Within the Grid
If the GridDataBoundGrid control in the tested application works is bound to a custom source, or you need to locate a row by the value in an unbound column, you can search within the grid itself rather than within its dataset. You can also use this approach if you need to search by the text displayed in grid cells rather than by the values stored in them. For example, if the grid displays data with a custom format applied, you can search for the row by the cells’s display text without having to know the actual values stored in the cells and their type.
The GridDataBoundGrid control does not have built-in methods for searching within the grid, so you will need to implement the search algorithm yourself. A general search approach implies that you iterate through the grid rows and on each iteration check whether the row meets the specified condition. The following example demonstrates how you can locate a particular row by iterating through the grid rows.
Example
JavaScript, JScript
function Main ()
{
var p, Grid, RowIndex;
// Obtain the application process and the grid object
p = Sys.Process ("DataBoundSortByDisplayMember");
Grid = p.WinFormsObject("Form1").WinFormsObject("gridDataBoundGrid1");
// Locate the row by cell text
RowIndex = FindRowByCellText (Grid, 2, "Ipoh Coffee");
if (RowIndex != -1)
ClickCell (Grid, RowIndex, 2)
else
Log.Error ("Row was not found.");
}
function FindRowByCellText (Grid, ColumnId, Text)
{
var StartRowIndex, EndRowIndex, ColIndex, i;
// Get indexes of the first and last data rows
StartRowIndex = Grid.GridCellsRange.Top;
EndRowIndex = Grid.GridCellsRange.Bottom;
// Convert the column's id to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId);
// Iterate through data rows
for (i=StartRowIndex; i<=EndRowIndex; i++)
// Compare the cell's display text with the specified string
if (Grid.Item(i, ColIndex).FormattedText.OleValue == Text)
return i; // Row is found;
return -1; // Row is not found
}
function ClickCell (Grid, RowIndex, ColumnId)
{
var ColIndex, rect;
// Convert the column's identifier to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId);
// Make cell visible
Grid.ScrollCellInView_3 (RowIndex, ColIndex);
// Get the cell coordinates
rect = Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell(RowIndex, ColIndex));
Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2);
}
function GetColIndexById (Grid, ColumnId)
{
if (aqObject.GetVarType(ColumnId) == varOleStr)
return Grid.NameToColIndex(ColumnId)
else
return ColumnId;
}
Python
def Main ():
# Obtain the application process and the grid object
p = Sys.Process ("DataBoundSortByDisplayMember")
Grid = p.WinFormsObject("Form1").WinFormsObject("gridDataBoundGrid1")
# Locate the row by cell text
RowIndex = FindRowByCellText (Grid, 2, "Ipoh Coffee")
if (RowIndex != -1):
ClickCell (Grid, RowIndex, 2)
else:
Log.Error ("Row was not found.")
def FindRowByCellText (Grid, ColumnId, Text):
# Get indexes of the first and last data rows
StartRowIndex = Grid.GridCellsRange.Top
EndRowIndex = Grid.GridCellsRange.Bottom
# Convert the column's id to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId)
# Iterate through data rows
for i in range(StartRowIndex, EndRowIndex):
# Compare the cell's display text with the specified string
if (Grid.Item[i, ColIndex].FormattedText.OleValue == Text):
return i # Row is found
return -1 # Row is not found
def ClickCell (Grid, RowIndex, ColumnId):
# Convert the column's identifier to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId)
# Make cell visible
Grid.ScrollCellInView_3 (RowIndex, ColIndex)
# Get the cell coordinates
rect = Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell(RowIndex, ColIndex))
Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2)
def GetColIndexById (Grid, ColumnId):
if (aqObject.GetVarType(ColumnId) == varOleStr):
return Grid.NameToColIndex(ColumnId)
else:
return ColumnId
VBScript
Sub Main
Dim p, Grid, RowIndex
' Obtain the application process and the grid object
Set p = Sys.Process ("DataBoundSortByDisplayMember")
Set Grid = p.WinFormsObject("Form1").WinFormsObject("gridDataBoundGrid1")
' Locate the row by cell text
RowIndex = FindRowByCellText (Grid, 2, "Ipoh Coffee")
If RowIndex <> -1 Then
Call ClickCell (Grid, RowIndex, 2)
Else
Call Log.Error ("Row was not found.")
End If
End Sub
Function FindRowByCellText (Grid, ColumnId, Text)
Dim StartRowIndex, EndRowIndex, ColIndex, i
' Get indexes of the first and last data rows
StartRowIndex = Grid.GridCellsRange.Top
EndRowIndex = Grid.GridCellsRange.Bottom
' Convert the column's identifier to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId)
' Iterate through data rows
For i=StartRowIndex To EndRowIndex
' Compare the cell's display text with the specified string
If Grid.Item(i, ColIndex).FormattedText.OleValue = Text Then
FindRowByCellText = i ' Row is found
Exit Function
End If
Next
FindRowByCellText = -1 ' Row is not found
End Function
Sub ClickCell (Grid, RowIndex, ColumnId)
Dim ColIndex, rect
' Convert the column's identifier to its index
ColIndex = GetColIndexById (Grid, ColumnId)
' Make cell visible
Call Grid.ScrollCellInView_3 (RowIndex, ColIndex)
' Get the cell coordinates
Set rect = Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell(RowIndex, ColIndex))
Call Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2)
End Sub
Function GetColIndexById (Grid, ColumnId)
If aqObject.GetVarType(ColumnId) = varOleStr Then
GetColIndexById = Grid.NameToColIndex(ColumnId)
Else
GetColIndexById = ColumnId
End If
End Function
DelphiScript
function FindRowByCellText (Grid, ColumnId, Text); forward;
procedure ClickCell (Grid, RowIndex, ColumnId); forward;
function GetColIndexById (Grid, ColumnId); forward;
procedure Main;
var p, Grid, RowIndex : OleVariant;
begin
// Obtain the application process and the grid object
p := Sys.Process ('DataBoundSortByDisplayMember');
Grid := p.WinFormsObject('Form1').WinFormsObject('gridDataBoundGrid1');
// Locate the row by cell text
RowIndex := FindRowByCellText (Grid, 2, 'Ipoh Coffee');
if RowIndex <> -1 then
ClickCell (Grid, RowIndex, 2)
else
Log.Error ('Row was not found.');
end;
function FindRowByCellText (Grid, ColumnId, Text);
var StartRowIndex, EndRowIndex, ColIndex, i : OleVariant;
begin
// Get indexes of the first and last data rows
StartRowIndex := Grid.GridCellsRange.Top;
EndRowIndex := Grid.GridCellsRange.Bottom;
// Convert the column's id to its absolute index
ColIndex := GetColIndexById (Grid, ColumnId);
// Iterate through data rows
for i := StartRowIndex to EndRowIndex do
// Compare the cell's display text with the specified string
if Grid.Item[i, ColIndex].FormattedText.OleValue = Text then
begin
Result := i; // Row is found
Exit;
end;
Result := -1; // Row is not found
end;
procedure ClickCell (Grid, RowIndex, ColumnId);
var ColIndex, rect : OleVariant;
begin
// Convert the column's identifier to its index
ColIndex := GetColIndexById (Grid, ColumnId);
// Make cell visible
Grid.ScrollCellInView_3 (RowIndex, ColIndex);
// Get the cell coordinates
rect := Grid.RangeInfoToRectangle (Grid.GridCellsRange.Cell(RowIndex, ColIndex));
Grid.Click (rect.X + rect.Width/2, rect.Y + rect.Height/2);
end;
function GetColIndexById (Grid, ColumnId);
begin
if aqObject.GetVarType(ColumnId) = varOleStr then
Result := Grid.NameToColIndex(ColumnId)
else
Result := ColumnId;
end;
C++Script, C#Script
function Main ()
{
var p, Grid, RowIndex;
// Obtain the application process and the grid object
p = Sys["Process"]("DataBoundSortByDisplayMember");
Grid = p["WinFormsObject"]("Form1")["WinFormsObject"]("gridDataBoundGrid1");
// Locate the row by cell text
RowIndex = FindRowByCellText (Grid, 2, "Ipoh Coffee");
if (RowIndex != -1)
ClickCell (Grid, RowIndex, 2)
else
Log["Error"]("Row was not found.");
}
function FindRowByCellText (Grid, ColumnId, Text)
{
var StartRowIndex, EndRowIndex, ColIndex, i;
// Get indexes of the first and last data rows
StartRowIndex = Grid["GridCellsRange"]["Top"];
EndRowIndex = Grid["GridCellsRange"]["Bottom"];
// Convert the column's id to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId);
// Iterate through data rows
for (i=StartRowIndex; i<=EndRowIndex; i++)
// Compare the cell's display text with the specified string
if (Grid["Item"](i, ColIndex)["FormattedText"]["OleValue"] == Text)
return i; // Row is found;
return -1; // Row is not found
}
function ClickCell (Grid, RowIndex, ColumnId)
{
var ColIndex, rect;
// Convert the column's identifier to its absolute index
ColIndex = GetColIndexById (Grid, ColumnId);
// Make cell visible
Grid["ScrollCellInView_3"](RowIndex, ColIndex);
// Get the cell coordinates
rect = Grid["RangeInfoToRectangle"](Grid["GridCellsRange"]["Cell"](RowIndex, ColIndex));
Grid["Click"](rect["X"] + rect["Width"]/2, rect["Y"] + rect["Height"]/2);
}
function GetColIndexById (Grid, ColumnId)
{
if (aqObject["GetVarType"](ColumnId) == varOleStr)
return Grid["NameToColIndex"](ColumnId)
else
return ColumnId;
}
Which Approach To Choose
In the previous sections, we have described two approaches for searching in the GridDataBoundGrid. Both approaches have their advantages and bottlenecks.
In general, searching in the grid’s dataset works faster. However, it has some strict limitations. First of all, you need to know the data types of dataset fields and specify the appropriate data as search values. In certain cases, the actual values stored in grid cells may significantly differ from what you see in the grid. This happens when the grid control is configured so that it displays data with a special format applied (for example, it may not display the time part of DateTime values), or when the grid uses lookup (foreign key) cells that hold values of one dataset field, but display values of another one. To determine the field data type, you can explore the grid’s data source object in the Object Browser, or ask the tested application’s developers.
Note also, that this approach cannot be used to search by values in columns that are not bound to any dataset field.
The approach that implies searching in the grid control itself does not depend on the grid cell’s data type, because it analyzes the cell’s display text. So, you do not need to know the grid cells’ data types. This approach is also suitable for searching in the grid that is not bound to any data source (for example, if it works in an unbound or virtual mode), or to perform search by values in unbound columns. However, the search algorithm suggested in this topic is simple and functions much slower than searching in the grid’s dataset, especially if the grid contains a large number of records. If you need better performance, you can implement a more effective search algorithm, for example, a binary search.
See Also
Working With Syncfusion GridDataBoundGrid
Accessing Rows, Columns and Cells in Syncfusion GridDataBoundGrid
Iterating Through Rows in Syncfusion GridDataBoundGrid
Obtaining and Setting Cell Values in Syncfusion GridDataBoundGrid