When testing an application that uses DataGridView controls, you may need to search for a specific record within the grid. For example, you may need to find a certain record to make sure that the data has been loaded into the grid correctly or to determine the position of a record within the grid. This topic describes two approaches for searching within the DataGridView control and explains how you can implement a custom search:
To perform these actions, TestComplete should have access to internal objects, properties and methods of the DataGridView control. For this purpose, the .NET Application Support and Microsoft Control Support plugins must be installed and enabled. When testing Microsoft DataGridView controls, use specific methods and properties of the corresponding |
Searching Within the Grid’s Dataset
If the DataGridView control 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 dataset is a universal approach that is free from the grid’s user interface limitations. You can also use this approach if you need to obtain and process values in the grid cells rather than their displayed representation.
To obtain the grid’s underlying dataset, use the DataSource
property of the grid control. Since the DataGridView 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. These methods search in the column of the currently sorted grid. 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). To search for a complex value (such as System.DateTime
), you need to create an instance of the corresponding .NET class (see Calling Functions From .NET Assemblies). If rows that match the search criteria are not found, Find
returns -1 and FindRows
returns an empty array (with no elements).
Below is an example that demonstrates how you can search for a grid row using the DataView.Find
method.
Example
JavaScript, JScript
function Main ()
{
var p, Grid, RowIndex;
// Obtain the grid object
p = Sys.Process ("DataGridViewSample");
Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1");
// Sort the grid data by the "Customer Name" column
Grid.ClickColumnHeader ("Customer Name");
// Locate a row by cell value
RowIndex = FindRowInDataset (Grid, "Samuel Clemens");
if (RowIndex >= 0)
Grid.ClickCell (RowIndex, "Customer Name");
else
Log.Error ("Row was not found.");
}
function FindRowInDataset (Grid, Value)
{
// Get the grid's DataView
var DataView = Grid.BindingContext.Item_2(Grid.DataSource, Grid.DataMember).List;
// Find data row containing the specified value
return DataView.Find (Value);
}
Python
def Main ():
# Obtain the grid object
p = Sys.Process ("DataGridViewSample")
Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1")
# Sort the grid data by the "Customer Name" column
Grid.ClickColumnHeader ("Customer Name")
# Locate a row by cell value
RowIndex = FindRowInDataset (Grid, "Samuel Clemens")
if (RowIndex >= 0):
Grid.ClickCell (RowIndex, "Customer Name")
else:
Log.Error ("Row was not found.")
def FindRowInDataset (Grid, Value):
# Get the grid's DataView
DataView = Grid.BindingContext.Item_2[Grid.DataSource, Grid.DataMember].List
# Find data row containing the specified value
return DataView.Find (Value)
VBScript
Sub Main
Dim p, Grid, RowIndex
' Obtain the grid object
Set p = Sys.Process ("DataGridViewSample")
Set Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1")
' Sort the grid data by the "Customer Name" column
Grid.ClickColumnHeader ("Customer Name")
' Locate a row by cell value
RowIndex = FindRowInDataset (Grid, "Samuel Clemens")
If RowIndex >= 0 Then
Call Grid.ClickCell (RowIndex, "Customer Name")
Else
Log.Error ("Row was not found.")
End If
End Sub
Function FindRowInDataset (Grid, Value)
Dim DataView
' Get the grid's DataView
Set DataView = Grid.BindingContext.Item_2(Grid.DataSource, Grid.DataMember).List.List
' Find data row containing the specified value
FindRowInDataset = DataView.Find (Value)
End Function
DelphiScript
function FindRowInDataset (Grid, Value);
var DataView : OleVariant;
begin
// Get the grid's DataView
DataView := Grid.BindingContext.Item_2[Grid.DataSource, Grid.DataMember].List.List;
// Find data row containing the specified value
Result := DataView.Find (Value);
end;
procedure Main;
var p, Grid, RowIndex : OleVariant;
begin
// Obtain the grid object
p := Sys.Process ('DataGridViewSample');
Grid := p.WinFormsObject('Form1').WinFormsObject('dataGridView1');
// Sort the grid data by the 'Customer Name' column
Grid.ClickColumnHeader ('Customer Name');
// Locate a row by cell value
RowIndex := FindRowInDataset (Grid, 'Samuel Clemens');
if RowIndex >= 0 then
Grid.ClickCell (RowIndex, 'Customer Name')
else
Log.Error ('Row was not found.');
end;
C++Script, C#Script
function Main ()
{
var p, Grid, RowIndex;
// Obtain the grid object
p = Sys["Process"]("DataGridViewSample");
Grid = p["WinFormsObject"]("Form1")["WinFormsObject"]("dataGridView1");
// Sort the grid data by the "Customer Name" column
Grid["ClickColumnHeader"]("Customer Name");
// Locate a row by cell value
RowIndex = FindRowInDataset (Grid, "Samuel Clemens");
if (RowIndex >= 0)
Grid["ClickCell"](RowIndex, "Customer Name");
else
Log["Error"]("Row was not found.");
}
function FindRowInDataset (Grid, Value)
{
// Get the grid's DataView
var DataView = Grid["BindingContext"]["Item_2"](Grid["DataSource"], Grid["DataMember"])["List"];
// Find data row containing the specified value
return DataView["Find"](Value);
}
Searching Within the Grid
If the DataGridView control in the tested application works in the unbound mode or if it is bound to a custom source, you should search within the grid itself rather that within its dataset. You should also search within the grid if it is configured so that it displays values with a custom formatting applied.
The DataGridView 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. For more information on how to iterate through the grid, see Iterating Through Rows in Microsoft DataGridView.
Below is an example that demonstrates how you can locate a particular row by iterating through the grid rows.
Example
JavaScript
function Main ()
{
var p, Grid, RowIndex;
// Obtain the grid object
p = Sys.Process ("DataGridViewSample");
Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1");
// Locate a row by cell value
RowIndex = FindRow (Grid, "Customer Name", "Samuel Clemens");
if (RowIndex >= 0)
Grid.ClickCell (RowIndex, "Customer Name");
else
Log.Error ("Row was not found.");
}
function FindRow (Grid, ColumnId, Value)
{
// Iterate through grid rows
for (let i=0; i<Grid.wRowCount; i++)
// Check the cell value in the specified column
if (equal(Grid.wValue(i, ColumnId), Value))
return i; // Row is found
return -1; // Row is not found
}
JScript
function Main ()
{
var p, Grid, RowIndex;
// Obtain the grid object
p = Sys.Process ("DataGridViewSample");
Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1");
// Locate a row by cell value
RowIndex = FindRow (Grid, "Customer Name", "Samuel Clemens");
if (RowIndex >= 0)
Grid.ClickCell (RowIndex, "Customer Name");
else
Log.Error ("Row was not found.");
}
function FindRow (Grid, ColumnId, Value)
{
// Iterate through grid rows
for (var i=0; i<Grid.wRowCount; i++)
// Check the cell value in the specified column
if (Grid.wValue(i, ColumnId) == Value)
return i; // Row is found
return -1; // Row is not found
}
Python
def Main ():
# Obtain the grid object
p = Sys.Process ("DataGridViewSample")
Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1")
# Locate a row by cell value
RowIndex = FindRow (Grid, "Customer Name", "Samuel Clemens")
if (RowIndex >= 0):
Grid.ClickCell (RowIndex, "Customer Name")
else:
Log.Error ("Row was not found.")
def FindRow (Grid, ColumnId, Value):
# Iterate through grid rows
for i in range(0, Grid.wRowCount-1):
# Check the cell value in the specified column
if (Grid.wValue[i, ColumnId] == Value):
return i # Row is found
return -1 # Row is not found
VBScript
Sub Main
Dim p, Grid, RowIndex
' Obtain the grid object
Set p = Sys.Process ("DataGridViewSample")
Set Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1")
' Locate a row by cell value
RowIndex = FindRow (Grid, "Customer Name", "Samuel Clemens")
If RowIndex >= 0 Then
Call Grid.ClickCell (RowIndex, "Customer Name")
Else
Log.Error ("Row was not found.")
End If
End Sub
Function FindRow (Grid, ColumnId, Value)
Dim i
' Iterate through grid rows
For i = 0 To Grid.wRowCount-1
' Check the cell value in the specified column
If Grid.wValue(i, ColumnId) = Value Then
FindRow = i ' Row is found
Exit Function
End If
Next
FindRow = -1 ' Row is not found
End Function
DelphiScript
function FindRow (Grid, ColumnId, Value);
var i : OleVariant;
begin
// Iterate through grid rows
for i :=0 to Grid.wRowCount-1 do
// Check the cell value in the specified column
if Grid.wValue[i, ColumnId].Equals(Value) then
begin
Result := i; // Row is found
Exit
end;
Result := -1; // Row is not found
end;
procedure Main;
var p, Grid, RowIndex : OleVariant;
begin
// Obtain the grid object
p := Sys.Process ('DataGridViewSample');
Grid := p.WinFormsObject('Form1').WinFormsObject('dataGridView1');
// Locate a row by cell value
RowIndex := FindRow (Grid, 'Customer Name', 'Samuel Clemens');
if RowIndex >= 0 then
Grid.ClickCell (RowIndex, 'Customer Name')
else
Log.Error ('Row was not found.');
end;
C++Script, C#Script
function Main ()
{
var p, Grid, RowIndex;
// Obtain the grid object
p = Sys["Process"]("DataGridViewSample");
Grid = p["WinFormsObject"]("Form1")["WinFormsObject"]("dataGridView1");
// Locate a row by cell value
RowIndex = FindRow (Grid, "Customer Name", "Samuel Clemens");
if (RowIndex >= 0)
Grid["ClickCell"](RowIndex, "Customer Name");
else
Log["Error"]("Row was not found.");
}
function FindRow (Grid, ColumnId, Value)
{
// Iterate through grid rows
for (var i=0; i<Grid["wRowCount"]; i++)
// Check the cell value in the specified column
if (Grid["wValue"](i, ColumnId) == Value)
return i; // Row is found
return -1; // Row is not found
}
The following example is a bit more complex. It demonstrates how to find a DataGridView row by values held in multiple cells.
Example
JavaScript, JScript
function Main ()
{
var p, Grid, ColumnIds, Values, RowIndex;
// Obtain the grid object
p = Sys.Process ("DataGridViewSample");
Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1");
// Locate a row by multiple values
ColumnIds = new Array ("Customer Name", "Product");
Values = new Array ("Susan McLaren", "MyMoney");
RowIndex = FindRowByMultipleValues (Grid, ColumnIds, Values);
if (RowIndex >= 0)
Grid.ClickCell (RowIndex, "Customer Name");
else
Log.Error ("Row was not found.");
}
function FindRowByMultipleValues (Grid, Columns, Values)
{
var match, i, j;
// Iterate through grid rows
for (i=0; i<Grid.wRowCount; i++)
{
match = true;
// Check cell values in the specified columns
for (j=0; j<Columns.length; j++)
if (Grid.wValue(i, Columns[j]) != Values[j])
{
match = false; // Cell value differs from the specified one
break;
}
if (match)
return i; // Row is found
}
return -1; // Row is not found
}
Python
def Main ():
# Obtain the grid object
p = Sys.Process ("DataGridViewSample")
Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1")
# Locate a row by multiple values
ColumnIds = list("Customer Name", "Product")
Values = list("Susan McLaren", "MyMoney")
RowIndex = FindRowByMultipleValues (Grid, ColumnIds, Values)
if (RowIndex >= 0):
Grid.ClickCell (RowIndex, "Customer Name")
else:
Log.Error ("Row was not found.")
def FindRowByMultipleValues (Grid, Columns, Values):
# Iterate through grid rows
for i in range(0, Grid.wRowCount-1):
match = True
# Check cell values in the specified columns
for j in range(0, Columns.length-1):
if (Grid.wValue[i, Columns[j]] != Values[j]):
match = False # Cell value differs from the specified one
break
if (match):
return i # Row is found
return -1 # Row is not found
VBScript
Sub Main
Dim p, Grid, ColumnIds, Values, RowIndex
' Obtain the grid object
Set p = Sys.Process ("DataGridViewSample")
Set Grid = p.WinFormsObject("Form1").WinFormsObject("dataGridView1")
' Locate a row by multiple values
ColumnIds = Array ("Customer Name", "Product")
Values = Array ("Susan McLaren", "MyMoney")
RowIndex = FindRowByMultipleValues (Grid, ColumnIds, Values)
If RowIndex >= 0 Then
Call Grid.ClickCell (RowIndex, "Customer Name")
Else
Log.Error ("Row was not found.")
End If
End Sub
Function FindRowByMultipleValues (Grid, Columns, Values)
Dim match, i, j
' Iterate through grid rows
For i=0 To Grid.wRowCount-1
match = True
' Check cell values in the specified columns
For j = 0 To UBound(Columns)
If Grid.wValue(i, Columns(j)) <> Values(j) Then
match = False' Cell value differs from the specified one
Exit For
End If
Next
If match Then
FindRowByMultipleValues = i ' Row is found
Exit Function
End If
Next
FindRowByMultipleValues = -1 ' Row is not found
End Function
DelphiScript
function FindRowByMultipleValues (Grid, Columns, Values);
var match, i, j : OleVariant;
begin
// Iterate through grid rows
for i := 0 to Grid.wRowCount-1 do
begin
match := true;
// Check cell values in the specified columns
for j := 0 to VarArrayHighBound(Columns, 1) do
if not Grid.wValue[i, Columns[j]].Equals(Values[j]) then
begin
match := false; // Cell value differs from the specified one
Break
end;
if match then
begin
Result := i; // Row is found
Exit
end
end;
Result := -1; // Row is not found
end;
procedure Main;
var p, Grid, ColumnIds, Values, RowIndex : OleVariant;
begin
// Obtain the grid object
p := Sys.Process ('DataGridViewSample');
Grid := p.WinFormsObject('Form1').WinFormsObject('dataGridView1');
// Locate a row by multiple values
ColumnIds := CreateVariantArray (0, 1);
Values := CreateVariantArray (0, 1);
ColumnIds[0] := 'Customer Name'; ColumnIds[1] := 'Product';
Values[0] := 'Susan McLaren'; Values[1] := 'MyMoney';
RowIndex := FindRowByMultipleValues (Grid, ColumnIds, Values);
if RowIndex >= 0 then
Grid.ClickCell (RowIndex, 'Customer Name')
else
Log.Error ('Row was not found.');
end;
C++Script, C#Script
function Main ()
{
var p, Grid, ColumnIds, Values, RowIndex;
// Obtain the grid object
p = Sys["Process"]("DataGridViewSample");
Grid = p["WinFormsObject"]("Form1")["WinFormsObject"]("dataGridView1");
// Locate a row by multiple values
ColumnIds = new Array ("Customer Name", "Product");
Values = new Array ("Susan McLaren", "MyMoney");
RowIndex = FindRowByMultipleValues (Grid, ColumnIds, Values);
if (RowIndex >= 0)
Grid["ClickCell"](RowIndex, "Customer Name");
else
Log["Error"]("Row was not found.");
}
function FindRowByMultipleValues (Grid, Columns, Values)
{
var match, i, j;
// Iterate through grid rows
for (i=0; i<Grid["wRowCount"]; i++)
{
match = true;
// Check cell values in the specified columns
for (j=0; j<Columns["length"]; j++)
if (Grid["wValue"](i, Columns[j]) != Values[j])
{
match = false; // Cell value differs from the specified one
break;
}
if (match)
return i; // Row is found
}
return -1; // Row is not found
}
See Also
Working With Microsoft DataGridView
Iterating Through Rows in Microsoft DataGridView
Obtaining and Setting Cell Values in Microsoft DataGridView
Selecting Cells in Microsoft DataGridView