Log In
[Expand]General Information
[Collapse]WinForms Controls
 [Expand]What's Installed
 [Expand]Build an Application
 [Collapse]Controls and Libraries
  [Expand]Forms and User Controls
  [Expand]Messages, Notifications and Dialogs
  [Expand]Editors and Simple Controls
  [Expand]Ribbon, Bars and Menu
  [Expand]Application UI Manager
  [Expand]Docking Library
  [Collapse]Data Grid
   [Expand]Getting Started
   [Expand]Binding to Data
   [Collapse]Grid View
    [Expand]Columns and Card Fields
    [Expand]Rows and Cards
    [Collapse]Row, Column and Cell Access API
      Tutorial: Identifying Rows
      Identifying Rows and Cards
      Accessing and Identifying Columns
    [Expand]Split Presentation
    [Expand]Cell Merging
    [Expand]Row Preview Sections
   [Expand]View Technology
   [Expand]Data Editing
   [Expand]Filtering and Locating Rows
   [Expand]Focus and Selection Handling
   [Expand]Processing Rows
   [Expand]Formatting Cell Values
   [Expand]Master-Detail Relationships
   [Expand]Asynchronous Image Load
   [Expand]Export and Printing
   [Expand]Appearance and Conditional Formatting
   [Expand]Batch Modifications
   [Expand]Hit Information
   [Expand]Popup Menus
   [Expand]Saving and Restoring Layouts
   [Expand]Visual Elements
   [Expand]Design-Time Features
   [Expand]End-User Capabilities
    Included Components
  [Expand]Vertical Grid
  [Expand]Pivot Grid
  [Expand]Tree List
  [Expand]Chart Control
  [Expand]Map Control
  [Expand]Rich Text Editor
  [Expand]Spell Checker
  [Expand]Form Layout Managers
  [Expand]Navigation Controls
  [Expand]PDF Viewer
  [Expand]TreeMap Control
 [Expand]Common Features
  Get More Help
 [Expand]API Reference
[Expand]ASP.NET Controls and MVC Extensions
[Expand]ASP.NET Bootstrap Controls
[Expand]WPF Controls
[Expand]Xamarin Controls
[Expand]Windows 10 App Controls
[Expand]Document Server
[Expand]Report Server
[Expand]eXpressApp Framework
[Expand]Cross-Platform Core Libraries
[Expand]Tools and Utilities
 End-User Documentation

Identifying Rows and Cards

When using Data Grid, you may need to perform operations on rows, cards or tiles using code. For instance, to focus a specific row/card/tile in code, you first need to get the corresponding row/card/tile identifier and assign it to the ColumnView.FocusedRowHandle property. Alternatively, you may wish to identify the type of the row or row value that is currently hovered. In these cases, you will need to know how to identify rows/cards/tiles.


In Grid Views and their descendants, data records are represented by rows. In Card Views and Layout Views, data records are represented by cards. In Tile Views, these records are displayed as tiles. In this topic, the term “row” will be used in a general way to refer to both rows in Grid Views, cards in Card/Layout Views and tiles in Tile Views.

Expanded Online Video

Learn about row identifiers and how they can help keep track of your grid.

Expanded Identifying Rows

Rows in views are identified by integer values called row handles. Each View associates its rows with these values using the following rules.

  • Each row has a row handle regardless of whether or not it is currently visible. A row may not be visible due to scrolling, and can be hidden within collapsed groups (in Grid Views).
  • Data row handles start from zero. The zero row handle is assigned to the first data row within a View. In this case, "first" implies the visual row order, but does not necessarily refer to the record's position within the bound data source. Then, successive integer values are assigned to additional data rows. The second data row handle is 1, the third data row handle is 2, etc. Note that modifying the row order changes the handles assigned to rows. This occurs, for example, when View data is sorted. As a result, a specific row handle may refer to different rows at different times.
  • Group row handles are negative. The first visible group row is identified by the -1 row handle, the second is identified by the -2 row handle, etc. Again, group row handles change when rows are reordered.
  • Each detail View clone provides handles for rows that are independent of other clones. As a result, row handles are unique in the GridControl.MainView and within each detail View clone. Please refer to the Detail Pattern and Clone Views topic for details on clone Views.

Visible rows can also be identified by their visible indexes within a View. These indexes also start from zero. Successive integers are assigned to additional visible rows. Note that visible indexes are also only unique in the GridControl.MainView or within a detail View clone.

Expanded Examples of Data Row Handles, Group Row Handles and Visible Indexes

Consider a row layout example that compares row handles and visible indexes. This will illustrate the assignment rules, as well as the relationship between row handles and visible indexes. First, the simplest example: a single View with no grouping applied. In this case, visible indexes match row handles. See the image below.

The following is a more complex example. It shows data row handles and group row handles. In this case, visible indexes do not match row handles.

In this example, the "City: Salzburg" group row contains two nested data rows. So the row handle of the last data row in the image ("Ipoh Coffee - 30 - $1,104.00") is equal to 4, not 2.

Finally, let's consider a sample grid control representing a master-detail relationship. As stated above, visible indexes and row handles are unique for the GridControl.MainView and for each detail View clone. The image below illustrates this.

Expanded Using Row Handles and Visible Indexes

Usually, Views identify their rows by row handles. For instance, the ColumnView.FocusedRowHandle property specifies the focused row by its handle. The ColumnView.FocusedRowChanged event passes handles of the previously and currently focused rows as parameters. When accessing or changing cell values, you will need to provide the appropriate row handle. When expanding a group row, the GridView.GroupRowExpanding event also identifies the affected group row by its handle.

Visible indexes are also used by Views to reference rows. For instance, the Grid View's GridView.TopRowIndex property scrolls the View to the row specified by its visible index. The ColumnView.GetNextVisibleRow method returns the visible index specified by the visible index of the preceding row.

Views provide methods to convert row handles to visible indexes and vice versa. The ColumnView.GetVisibleIndex and ColumnView.GetVisibleRowHandle methods are used for this purpose.

Expanded Obtaining Data Rows and Row Indexes in the Datasource

Row handles and visible indexes reflect the visual order of rows in a View, and these may change as rows change their positions or visibility status. In many cases, the best solution for referring to specific rows is to use objects that represent records in the bound data source (for instance, System.Data.DataRow objects if the data source is a System.Data.DataTable).

Consider an example in which you need to change values in a specific column for a subset of rows. The incorrect and correct approaches are illustrated below.

Incorrect Approach

To set a row value, the ColumnView.SetRowCellValue method can be used. This method requires a parameter that specifies a target row handle.

Store row handles of the rows that are to be modified. Next, call the SetRowCellValue method for each row handle. With this approach, however, the incorrect record might be modified if data is sorted or filtered against the target column. If data is sorted or filtered by the target column, the modification of a single row value may affect the order of rows. Even after a single modification, the stored row handles may point to incorrect rows, and using these row handles in subsequent calls to the SetRowCellValue method will change the wrong rows.

Correct Approach

The correct approach in this example is to use row objects instead of row handles. First, obtain the target row objects. Then modify them using the methods provided by the row objects.

To get row objects that correspond to specific row handles, use the ColumnView.GetRow or ColumnView.GetDataRow method. The GetRow method can be applied regardless of the bound data source type, while the GetDataRow method is only applicable if the bound data source is a System.Data.DataTable or System.Data.DataView object.

In specific cases, you may need to obtain indexes of rows in the bound data source that correspond to specific row handles in Views. To do this, use the ColumnView.GetDataSourceRowIndex method. To get a row's handle by its index in the data source, use the ColumnView.GetRowHandle method.

Expanded Special Row Handles

In addition to regular data rows and group rows, Views in the Grid Control can display special rows, identified by unique row handles. There is also a specific row handle reserved by the Grid Control used to identify a row that does not exist. Refer to the following table for information on row handles that correspond to these special rows.

Row Row Handle Description
Auto Filter Row

(supported by GridViews and descendants)

GridControl.AutoFilterRowHandle An end-user can filter data on the fly using the Auto Filter Row. Typing text within this row automatically creates and applies a filter to the View. See Auto Filter Row for more information.
New Item Row/Card

(supported by GridViews, CardViews, LayoutViews and their descendants)

GridControl.NewItemRowHandle The New Item Row/Card allows an end-user to add new records to the data source, provided that the addition of rows to the data source is permitted. See the Adding and Deleting Records topic for more information.

Refer to the New Item Row/Card topic for details on this row.

Invalid Row

(supported by GridViews, CardViews, LayoutViews and their descendants)

GridControl.InvalidRowHandle Generally, this row handle corresponds to a row that does not exist in the View.

When handling specific row-related events, you may notice that an event's RowHandle parameter is set to InvalidRowHandle. For instance, when all group rows are collapsed at once using the GridView.CollapseAllGroups method, the GridView.GroupRowCollapsing event fires. Its RowHandle parameter will be set to InvalidRowHandle.

Using these special row handles is similar to using regular row handles, but with some restrictions. For instance, if the Auto Filter Row or New Item Row/Card is visible and you need to focus any of these rows, set the View's ColumnView.FocusedRowHandle property to GridControl.AutoFilterRowHandle or GridControl.NewItemRowHandle. Note that it is not possible to clear focus in the View by setting the ColumnView.FocusedRowHandle property to GridControl.InvalidRowHandle.

For regular data rows and the auto-filter row, you can set cell values using the ColumnView.SetRowCellValue method. For the New Item Row/Card, this method is only in effect when a new row/card is being added (immediately after the ColumnView.AddNewRow method has been called, or the Append button of the embedded navigator has been clicked).

Expanded See Also

How would you rate this topic?​​​​​​​