Sorting Data in Developer Express XtraGrid

Applies to TestComplete 14.72, last modified on April 22, 2021

The XtraGrid control lets the end users sort the displayed data. This topic describes the approaches that can be used to sort the grid data from test scripts:

To perform these actions, TestComplete should have access to internal objects, properties and methods of the XtraGrid control. For this purpose, the .NET Application Support and Developer Express Control Support plugins must be installed and enabled. The latter lets you work with the XtraGrid control using methods and properties of the DevExpressXtraGrid object. Without this plugin, you will not be able to work with XtraGrid controls using their internal methods and properties.

When testing Developer Express XtraGrid controls, use specific methods and properties of the corresponding DevExpressXtraGrid object. You can call these methods and properties from your keyword tests, as well as from scripts. This topic describes how to work with an object’s properties and methods from your scripts. However, when testing an XtraGrid control from your keyword test, you can use the same methods and properties calling them from keyword test operations. For more information, see Keyword Tests Basic Operations.

Simulating Column Headers Clicks

It is possible to sort the data displayed in the XtraGrid control by clicking on the header of the column that you want to sort. The next click on the same header switches the sort direction (from ascending to descending, and vice versa). After a click, the previous sort conditions are replaced with sorting by the clicked column. In order to sort the data by this column preserving other sort conditions, you should hold the Shift key while clicking the column header. Holding Ctrl while clicking the header removes sorting by this column, preserving sorting by other columns.

With TestComplete, you can simulate clicks as well as Shift- and Ctrl-clicks on the XtraGrid column headers using the ClickColumnHeader action of the DevExpressXtraGrid or DevExpressXtraGridView objects. Both of these actions perform a mouse click over the specified column header, but the DevExpressXtraGrid object deals with the columns of the main data view, while the DevExpressXtraGridView object affects the columns of the corresponding child views. Note that it is only possible to simulate clicks on column headers if they are displayed, that is, if the view’s OptionsView.ShowColumnHeaders native property is True. If this property is False, the column headers are hidden, so an attempt to simulate a click on them will cause an error.

The following example demonstrates how you can sort data in the XtraGrid control by simulating clicks on column headers.

The example works with the GridTutorials application.

How to get the application

JavaScript, JScript

function Main()
{
 var p, frmMain, Grid;

  // Obtain the application process and its main form
  p = Sys.Process("GridTutorials");
  frmMain = p.WinFormsObject("frmMain");
  // Select the "Master-Detail" demo
  frmMain.WinFormsObject("gcNavigations").WinFormsObject("listBoxControl1").SelectedItem = "Master-Detail";
  // Obtain the grid control
  Grid = frmMain.WinFormsObject("pcMain").WinFormsObject("gcContainer").WinFormsObject("Form1").WinFormsObject("gridControl1");

  // Sort the root table data
  Grid.ClickColumnHeader ("FirstName");
  Grid.ClickColumnHeader ("LastName", skShift);

  // Sort the child table data by the "Name" column
  Grid.wChildView(0, 0).ClickColumnHeader ("Name");
}

Python

def Main():

  # Obtain the application process and its main form
  p = Sys.Process("GridTutorials")
  frmMain = p.WinFormsObject("frmMain")
  # Select the "Master-Detail" demo 
  frmMain.WinFormsObject("gcNavigations").WinFormsObject("listBoxControl1").SelectedItem = "Master-Detail"
  # Obtain the grid control
  Grid = frmMain.WinFormsObject("pcMain").WinFormsObject("gcContainer").WinFormsObject("Form1").WinFormsObject("gridControl1")

  # Sort the root table data
  Grid.ClickColumnHeader ("FirstName")
  Grid.ClickColumnHeader ("LastName", skShift)

  # Sort the child table data by the "Name" column
  Grid.wChildView[0, 0].ClickColumnHeader ("Name")

VBScript

Sub Main
  Dim p, frmMain, Grid

  ' Obtain the application process and its main form
  Set p = Sys.Process("GridTutorials")
  Set frmMain = p.WinFormsObject("frmMain")
  ' Select the "Master-Detail" demo
  frmMain.WinFormsObject("gcNavigations").WinFormsObject("listBoxControl1").SelectedItem = "Master-Detail"
  ' Obtain the grid control
  Set Grid = frmMain.WinFormsObject("pcMain").WinFormsObject("gcContainer").WinFormsObject("Form1").WinFormsObject("gridControl1")

  ' Sort the root table data
  Call Grid.ClickColumnHeader ("FirstName")
  Call Grid.ClickColumnHeader ("LastName", skShift)

  ' Sort the child table data by the "Name" column
  Call Grid.wChildView(0, 0).ClickColumnHeader ("Name")
End Sub

DelphiScript

procedure Main;
var p, frmMain, Grid : OleVariant;
begin
  // Obtain the application process and its main form
  p := Sys.Process('GridTutorials');
  frmMain := p.WinFormsObject('frmMain');
  // Select the "Master-Detail" demo
  frmMain.WinFormsObject('gcNavigations').WinFormsObject('listBoxControl1').SelectedItem := 'Master-Detail';
  // Obtain the grid control
  Grid := frmMain.WinFormsObject('pcMain').WinFormsObject('gcContainer').WinFormsObject('Form1').WinFormsObject('gridControl1');

  // Sort the root table data
  Grid.ClickColumnHeader ('FirstName');
  Grid.ClickColumnHeader ('LastName', skShift);

  // Sort the child table data by the "Name" column
  Grid.wChildView(0,0).ClickColumnHeader ('Name');
end;

C++Script, C#Script

function Main()
{
 var p, frmMain, Grid;

  // Obtain the application process and its main form
  p = Sys["Process"]("GridTutorials");
  frmMain = p["WinFormsObject"]("frmMain");
  // Select the "Master-Detail" demo
  frmMain["WinFormsObject"]("gcNavigations")["WinFormsObject"]("listBoxControl1")["SelectedItem"] = "Master-Detail";
  // Obtain the grid control
  Grid = frmMain["WinFormsObject"]("pcMain")["WinFormsObject"]("gcContainer")["WinFormsObject"]("Form1")["WinFormsObject"]("gridControl1");

  // Sort the root table data
  Grid["ClickColumnHeader"] ("FirstName");
  Grid["ClickColumnHeader"] ("LastName", skShift);

  // Sort the child table data by the "Name" column
  Grid["wChildView"](0, 0)["ClickColumnHeader"] ("Name");
}

Using XtraGrid Internal Members

It is possible to sort the data displayed in the XtraGrid control using its internal properties and methods. Each XtraGrid column has the SortOrder property that specifies the column’s sort order. You can use this property to determine or set the sort order. When setting this property in scripts, you can use one of the following string values: “Ascending”, “Descending” or “None”

This approach is universal for the XtraGrid control and does not depend on the layout type used by the grid and it works for all supported layouts (grid, banded, card and others).

Example

The example works with the GridMainDemo application.

How to get the application

View example description

JavaScript

function Main ()
{
  var p, frmMain, Grid, OrdersView;

  // Obtain the application process and its main form
  p = Sys.Process("GridMainDemo");
  frmMain = p.WinFormsObject("frmMain");
  frmMain.Maximize();
  // Select the "Master-Detail" demo
  frmMain.WinFormsObject("gcNavigations").WinFormsObject("navBarControl1").Groups.Item_2(1).SelectedLinkIndex = 0;
  // Obtain the grid control
  Grid = frmMain.WinFormsObject("panelControl1").WinFormsObject("gcContainer").WinFormsObject("MasterDetail").WinFormsObject("gridControl1");

  // Sort the "Order Details" view by the "Unit Price" column
  OrdersView = GetView (Grid, "Order Details");
  Sort (Grid, OrdersView, "Unit Price", "Descending");
  aqUtils.Delay (1000);

  // Sort the main view by the "Country" column
  Sort (Grid, null, "Company Name", "Ascending");
  aqUtils.Delay (1000);

  // Remove sorting by the "Region" column
  Sort (Grid, null, "Region", "None");
  aqUtils.Delay (1000);
}

function Sort (Grid, View, ColumnId, SortOrder)
{
  // Get the column object
  var Column = GetColumn (Grid, View, ColumnId);
  // Sort the view data by this column
  Column.SortOrder = SortOrder;
}

// Returns the view object by its caption or index
function GetView (Grid, ViewId)
{
  // Check if the view is specified by caption or index
  if (equal(aqObject.GetVarType (ViewId), varOleStr))
  {
    // Search for the view by its caption
    for (let i=0; i<Grid.wViewCount; i++)
      if (Grid.wView(i) == ViewId)
        return Grid.Views.Item(i); // View is found
    return null; // View is not found
  }
  else
    // Get the view by index
    return Grid.Views.Item(ViewId);
}

// Returns a column object specified by caption or index
function GetColumn (Grid, View, ColumnId)
{
  var Columns, Col, i;

  // Get the grid view object, if it is not specified
  if (strictEqual(View, null))
    View = Grid.MainView;

  Columns = View.Columns;
  // Check if the column is specified by caption or index
  if (aqObject.GetVarType (ColumnId) == varOleStr)
  {
    // Search for the column by its caption
    for (let i=0; i<Columns.Count; i++)
    {
      Col = Columns.Item_2 (i);
      if (Col.Caption.OleValue == ColumnId)
        return Col; // The column is found
    }
    return null; // The column is not found
  }
  else
    // The column is specified by index
    return Columns.Item_2 (ColumnId);
}

JScript

function Main ()
{
  var p, frmMain, Grid, OrdersView;

  // Obtain the application process and its main form
  p = Sys.Process("GridMainDemo");
  frmMain = p.WinFormsObject("frmMain");
  frmMain.Maximize();
  // Select the "Master-Detail" demo
  frmMain.WinFormsObject("gcNavigations").WinFormsObject("navBarControl1").Groups.Item_2(1).SelectedLinkIndex = 0;
  // Obtain the grid control
  Grid = frmMain.WinFormsObject("panelControl1").WinFormsObject("gcContainer").WinFormsObject("MasterDetail").WinFormsObject("gridControl1");

  // Sort the "Order Details" view by the "Unit Price" column
  OrdersView = GetView (Grid, "Order Details");
  Sort (Grid, OrdersView, "Unit Price", "Descending");
  aqUtils.Delay (1000);

  // Sort the main view by the "Country" column
  Sort (Grid, null, "Company Name", "Ascending");
  aqUtils.Delay (1000);

  // Remove sorting by the "Region" column
  Sort (Grid, null, "Region", "None");
  aqUtils.Delay (1000);
}

function Sort (Grid, View, ColumnId, SortOrder)
{
  // Get the column object
  var Column = GetColumn (Grid, View, ColumnId);
  // Sort the view data by this column
  Column.SortOrder = SortOrder;
}

// Returns the view object by its caption or index
function GetView (Grid, ViewId)
{
  // Check if the view is specified by caption or index
  if (aqObject.GetVarType (ViewId) == varOleStr)
  {
    // Search for the view by its caption
    for (var i=0; i<Grid.wViewCount; i++)
      if (Grid.wView(i) == ViewId)
        return Grid.Views.Item(i); // View is found
    return null; // View is not found
  }
  else
    // Get the view by index
    return Grid.Views.Item(ViewId);
}

// Returns a column object specified by caption or index
function GetColumn (Grid, View, ColumnId)
{
  var Columns, Col, i;

  // Get the grid view object, if it is not specified
  if (View == null)
    View = Grid.MainView;

  Columns = View.Columns;
  // Check if the column is specified by caption or index
  if (aqObject.GetVarType (ColumnId) == varOleStr)
  {
    // Search for the column by its caption
    for (i=0; i<Columns.Count; i++)
    {
      Col = Columns.Item_2 (i);
      if (Col.Caption.OleValue == ColumnId)
        return Col; // The column is found
    }
    return null; // The column is not found
  }
  else
    // The column is specified by index
    return Columns.Item_2 (ColumnId);
}

Python

def Main ():

  # Obtain the application process and its main form
  p = Sys.Process("GridMainDemo")
  frmMain = p.WinFormsObject("frmMain")
  frmMain.Maximize()
  # Select the "Master-Detail" demo
  frmMain.WinFormsObject("gcNavigations").WinFormsObject("navBarControl1").Groups.Item_2[1].SelectedLinkIndex = 0
  # Obtain the grid control
  Grid = frmMain.WinFormsObject("panelControl1").WinFormsObject("gcContainer").WinFormsObject("MasterDetail").WinFormsObject("gridControl1")

  # Sort the "Order Details" view by the "Unit Price" column
  OrdersView = GetView (Grid, "Order Details")
  Sort (Grid, OrdersView, "Unit Price", "Descending")
  aqUtils.Delay (1000)

  # Sort the main view by the "Country" column
  Sort (Grid, None, "Company Name", "Ascending")
  aqUtils.Delay (1000)

  # Remove sorting by the "Region" column
  Sort (Grid, None, "Region", "None")
  aqUtils.Delay (1000)

def Sort (Grid, View, ColumnId, SortOrder):
  # Get the column object
  Column = GetColumn (Grid, View, ColumnId)
  # Sort the view data by this column
  Column.SortOrder = SortOrder

# Returns the view object by its caption or index
def GetView (Grid, ViewId):
  # Check if the view is specified by caption or index
  if (aqObject.GetVarType (ViewId) == varOleStr):
    # Search for the view by its caption
    for i in range(0, Grid.wViewCount-1):
      if (Grid.wView[i] == ViewId):
        return Grid.Views.Item[i] # View is found
    return None # View is not found
  else:
    # Get the view by index
    return Grid.Views.Item[ViewId]

# Returns a column object specified by caption or index
def GetColumn (Grid, View, ColumnId):

  # Get the grid view object, if it is not specified
  if (View == None):
    View = Grid.MainView

  Columns = View.Columns
  # Check if the column is specified by caption or index
  if (aqObject.GetVarType (ColumnId) == varOleStr):
    # Search for the column by its caption
    for i in range(0, Columns.Count-1):
      Col = Columns.Item_2 [i]
      if (Col.Caption.OleValue == ColumnId):
        return Col # The column is found
    return None # The column is not found
  else:
    # The column is specified by index
    return Columns.Item_2 [ColumnId]

VBScript

Sub Main
  Dim p, frmMain, Grid, OrdersView

  ' Obtain the application process and its main form
  Set p = Sys.Process("GridMainDemo")
  Set frmMain = p.WinFormsObject("frmMain")
  frmMain.Maximize
  ' Select the "Master-Detail" demo
  frmMain.WinFormsObject("gcNavigations").WinFormsObject("navBarControl1").Groups.Item_2(1).SelectedLinkIndex = 0
  ' Obtain the grid control
  Set Grid = frmMain.WinFormsObject("panelControl1").WinFormsObject("gcContainer").WinFormsObject("MasterDetail").WinFormsObject("gridControl1")

  ' Sort the "Order Details" view by the "Unit Price" column
  Set OrdersView = GetView ("Order Details")
  Call Sort (Grid, OrdersView, "Unit Price", "Descending")
  aqUtils.Delay 1000

  ' Sort the main view by the "Country" column
  Call Sort (Grid, Nothing, "Company Name", "Ascending")
  aqUtils.Delay 1000

  ' Remove sorting by the "Region" column
  Call Sort (Grid, Nothing, "Region", "None")
  aqUtils.Delay 1000
End Sub

Sub Sort (Grid, View, ColumnId, SortOrder)
  Dim Column
  ' Get the column object
  Set Column = GetColumn (Grid, View, ColumnId)
  ' Sort the view data by this column
  Column.SortOrder = SortOrder
End Sub

' Returns the view object by its caption or index
Function GetView (Grid, ViewId)
  ' Check if the view is specified by caption or index
  If aqObject.GetVarType (ViewId) = varOleStr Then
    ' Search for the view by its caption
    For i = 0 To Grid.wViewCount-1
      If Grid.wView(i) = ViewId Then
        Set GetView = Grid.Views.Item(i) ' View is found
        Exit Function
      End If
    Next
    Set GetView = Nothing ' View is not found
  Else
    ' Get the view by index
    Set GetView = Grid.Views.Item(ViewId)
  End If
End Function

' Returns a column object specified by caption or index
Function GetColumn (Grid, View, ColumnId)
  Dim Columns, Col, i

  ' Get the grid view, if it is not specified
  If View Is Nothing Then
    Set View = Grid.MainView
  End If

  Set Columns = View.Columns
  ' Check if the column is specified by caption or index
  If aqObject.GetVarType (ColumnId) = varOleStr Then
    ' Search for the column by its caption
    For i = 0 To Columns.Count-1
      Set Col = Columns.Item_2 (i)
      If Col.Caption.OleValue = ColumnId Then
        Set GetColumn = Col ' The column is found
        Exit Function
      End If
    Next
    Set GetColumn = Nothing ' The column is not found
  Else
    ' The column is specified by index
    Set GetColumn = Columns.Item_2 (ColumnId)
  End If
End Function

DelphiScript

procedure Sort (Grid, ViewId, ColumnId, SortOrder); forward;
function GetView (Grid, ViewId); forward;
function GetColumn (Grid, View, ColumnId); forward;

procedure Main;
var p, frmMain, Grid, OrdersView : OleVariant;
begin
  // Obtain the application process and its main form
  p := Sys.Process('GridMainDemo');
  frmMain := p.WinFormsObject('frmMain');
  frmMain.Maximize;
  // Select the 'Master-Detail' demo
  frmMain.WinFormsObject('gcNavigations').WinFormsObject('navBarControl1').Groups.Item_2(1).SelectedLinkIndex := 0;
  // Obtain the grid control
  Grid := frmMain.WinFormsObject('panelControl1').WinFormsObject('gcContainer').WinFormsObject('MasterDetail').WinFormsObject('gridControl1');

  // Sort the 'Order Details' view by the 'Unit Price' column
  OrdersView := GetView (Grid, 'Order Details');
  Sort (Grid, OrdersView, 'Unit Price', 'Descending');
  aqUtils.Delay (1000);

  // Sort the main view by the 'Country' column
  Sort (Grid, nil, 'Company Name', 'Ascending');
  aqUtils.Delay (1000);

  // Remove sorting by the 'Region' column
  Sort (Grid, nil, 'Region', 'None');
  aqUtils.Delay (1000);
end;

procedure Sort (Grid, ViewId, ColumnId, SortOrder);
var Column : OleVariant;
begin
  // Get the column object
  Column := GetColumn (Grid, View, ColumnId);
  // Sort the view data by this column
  Column.SortOrder := SortOrder;
end;

// Returns the view object by its caption or index
function GetView (Grid, ViewId);
var i : OleVariant;
begin
  // Check if the view is specified by caption or index
  if aqObject.GetVarType (ViewId) = varOleStr then
  begin
    // Search for the view by its caption
    for i := 0 to Grid.wViewCount-1 do
      if Grid.wView[i] = ViewId then
      begin
        Result := Grid.Views.Item[i]; // View is found
        Exit;
      end;
    Result := nil; // View is not found
  end
  else
    // Get the view by index
    Result := Grid.Views.Item[ViewId];
end;

// Returns a column object specified by caption or index
function GetColumn (Grid, View, ColumnId);
var Columns, Col, i : OleVariant;
begin
  // Get the grid view object, if it is not specified
  if View = nil then
    View := Grid.MainView;

  Columns := View.Columns;
  // Check if the column is specified by caption or index
  if aqObject.GetVarType (ColumnId) = varOleStr then
  begin
    // Search for the column by its caption
    for i := 0 to Columns.Count-1 do
    begin
      Col := Columns.Item_2[i];
      if Col.Caption.OleValue = ColumnId then
      begin
        Result := Col; // The column is found
        Exit
      end
    end;
    Result := nil; // The column is not found
  end
  else
    // The column is specified by index
    Result := Columns.Item_2[ColumnId];
end;

C++Script, C#Script

function Main ()
{
  var p, frmMain, Grid, OrdersView;

  // Obtain the application process and its main form
  p = Sys["Process"]("GridMainDemo");
  frmMain = p["WinFormsObject"]("frmMain");
  frmMain["Maximize"]();
  // Select the "Master-Detail" demo
  frmMain["WinFormsObject"]("gcNavigations")["WinFormsObject"]("navBarControl1")["Groups"]["Item_2"](1)["SelectedLinkIndex"] = 0;
  // Obtain the grid control
  Grid = frmMain["WinFormsObject"]("panelControl1")["WinFormsObject"]("gcContainer")["WinFormsObject"]("MasterDetail")["WinFormsObject"]("gridControl1");

  // Sort the "Order Details" view by the "Unit Price" column
  OrdersView = GetView (Grid, "Order Details");
  Sort (Grid, OrdersView, "Unit Price", "Descending");
  aqUtils["Delay"] (1000);

  // Sort the main view by the "Country" column
  Sort (Grid, null, "Company Name", "Ascending");
  aqUtils["Delay"] (1000);

  // Remove sorting by the "Region" column
  Sort (Grid, null, "Region", "None");
  aqUtils["Delay"] (1000);
}

function Sort (Grid, ViewId, ColumnId, SortOrder)
{
  // Get the column object
  var Column = GetColumn (Grid, View, ColumnId);
  // Sort the view data by this column
  Column["SortOrder"] = SortOrder;
}

// Returns the view object by its caption or index
function GetView (Grid, ViewId)
{
  // Check if the view is specified by caption or index
  if (aqObject["GetVarType"] (ViewId) == varOleStr)
  {
    // Search for the view by its caption
    for (var i=0; i<Grid["wViewCount"]; i++)
      if (Grid["wView"](i) == ViewId)
        return Grid["Views"]["Item"](i); // View is found
    return null; // View is not found
  }
  else
    // Get the view by index
    return Grid["Views"]["Item"](ViewId);
}

// Returns a column object specified by caption or index
function GetColumn (Grid, View, ColumnId)
{
  var Columns, Col, i;

  // Get the grid view object, if it is not specified
  if (View == null)
    View = Grid["MainView"];

  Columns = View["Columns"];
  // Check if the column is specified by caption or index
  if (aqObject["GetVarType"] (ColumnId) == varOleStr)
  {
    // Search for the column by its caption
    for (i=0; i<Columns["Count"]; i++)
    {
      Col = Columns["Item_2"](i);
      if (Col["Caption"]["OleValue"] == ColumnId)
        return Col; // The column is found
    }
    return null; // The column is not found
  }
  else
    // The column is specified by index
    return Columns["Item_2"](ColumnId);
}

See Also

Working With Developer Express XtraGrid
Accessing Views in Developer Express XtraGrid
ClickColumnHeader Action (Grid Controls)

Highlight search results