Programming with Table Controls
- Updated2023-02-21
- 13 minute(s) read
Programming with Table Controls
This topic describes how to complete the following tasks programmatically.
- Adding rows, columns, and cells to a table
- Binding to a DataSocket source
- Copying and pasting data
- Creating a table control
- Customizing table cells
- Customizing table rows and columns
- Customizing the context menu
- Deleting rows and columns
- Obtaining and deleting the values of cell ring items
- Obtaining the number of rows and columns
- Optimizing performance
- Searching for values
- Sorting values
- Specifying an active cell or range of cells
- Specifying default values for cells
- Specifying range checking for numeric cells
- Specifying the type of data a cell can contain
Creating a Table Control
Use NewCtrl to create a table control.
int tableCtrl;
tableCtrl = NewCtrl (panelHandle, CTRL_TABLE_LS, "Table Control", 25, 25);
Adding Rows, Columns, and Cells to a Table
You can create an arbitrary number of rows and columns on a table control. As you do so, you create table cells that store the data within the table control.
InsertTableColumns (panelHandle, tableCtrl, -1, 3, VAL_USE_MASTER_CELL_TYPE);
InsertTableRows (panelHandle, tableCtrl, -1, 5, VAL_USE_MASTER_CELL_TYPE);
Refer to the specifying the type of data a cell can contain section for more information.
Deleting Rows and Columns
int numToDelete, index;
GetCtrlVal (panelHandle, PANEL_IDXDEL, &index);
GetCtrlVal (panelHandle, PANEL_TODEL, &numToDelete);
DeleteTableColumns (panelHandle, tableCtrl, index, numToDelete);
DeleteTableRows (panelHandle, tableCtrl, index, numToDelete);
Specifying the Type of Data a Cell Can Contain
Each cell has one of the following types associated with it:
- Numeric—Contains numeric data.
- String—Contains text data.
- Picture—Contains image data.
- Ring—Contains a list of items from which you can select a cell value.
- Combo box—Contains text data and a list of items from which you can select a cell value. You also can enter your own values in combo box cells.
- Button—Contains a label that you can press.
The cell type determines what type of data you can store in each cell: numeric, text, or bitmap image.
// Table cell holds numeric data.
SetTableCellAttribute (panelHandle, tableCtrl, MakePoint (1, 1), ATTR_CELL_TYPE, VAL_CELL_NUMERIC);
SetTableCellVal (panelHandle, tableCtrl, MakePoint (1, 1), 35.0);
// Table cell holds text data.
SetTableCellAttribute (panelHandle, tableCtrl, MakePoint (1, 2), ATTR_CELL_TYPE, VAL_CELL_STRING);
SetTableCellVal (panelHandle, tableCtrl, MakePoint (1, 2), "String");
// Table cell holds image data.
int bitmapID;
SetTableCellAttribute (panelHandle, tableCtrl, MakePoint (1, 3), ATTR_CELL_TYPE, VAL_CELL_PICTURE);
SetTableCellAttribute (panelHandle, tableCtrl, MakePoint (1, 3), ATTR_FIT_MODE, VAL_PICT_CENTER);
GetBitmapFromFile ("c:\temp\file_save.ico", &bitmapID);
SetTableCellVal (panelHandle, tableCtrl, MakePoint (1, 3), bitmapID);
// Table cell holds a list of items.
Point ringCellPoint;
ringCellPoint = MakePoint (1, 4);
SetTableCellAttribute (panelHandle, tableCtrl, ringCellPoint, ATTR_CELL_TYPE, VAL_CELL_RING);
InsertTableCellRingItem (panelHandle, tableCtrl, ringCellPoint, -1, "Pass");
InsertTableCellRingItem (panelHandle, tableCtrl, ringCellPoint, -1, "Fail");
SetTableCellVal (panelHandle, tableCtrl, ringCellPoint, "Pass");
// Table cell holds a combo box.
SetTableCellAttribute (panelHandle, tableCtrl, MakePoint (1, 5), ATTR_CELL_TYPE, VAL_CELL_COMBO_BOX);
SetTableCellVal (panelHandle, tableCtrl, MakePoint (1, 5), "Combo Box");
// Table cell holds a button.
SetTableCellAttribute (panelHandle, tableCtrl, MakePoint (1, 6), ATTR_CELL_TYPE, VAL_CELL_BUTTON);
SetTableCellVal (panelHandle, tableCtrl, MakePoint (1, 6), "Button");
You can change the cell type to store all three types of values simultaneously in one cell, but only the value corresponding to the current cell type is visible and operable. For example, if you have a numeric cell with a value of 2.0 and you change that cell to be a string cell with a value of hello, when you change the cell back to a numeric cell, the value of the numeric cell remains 2.0.
Button, ring, combo box, and string cells can share the same string value, which means that changing a cell from one of these types to another does not change the value of the cell. Because values that appear in a ring cell must exist in the value list of the ring cell, if you change a cell type to a ring cell, its value might be changed to the first item in the value list.
Setting Values for a Range of Cells
You can set and get the values of a range of cells, such as those of an entire row or a group of rows.
/* Set the values from an array containing new values for each cell. */
int i;
int valArray[20];
InsertTableColumns (panelHandle, tableCtrl, -1, 3, VAL_CELL_NUMERIC);
InsertTableRows (panelHandle, tableCtrl, -1, 6, VAL_CELL_NUMERIC);
for (i=0; i<20; i++)
{
valArray[i] = i;
}
SetTableCellRangeVals (panelHandle, tableCtrl, VAL_TABLE_ENTIRE_RANGE, valArray, VAL_ROW_MAJOR);
/* Propagate a single value through a range of cells. */
InsertTableColumns (panelHandle, tableCtrl, -1, 3, VAL_CELL_STRING);
InsertTableRows (panelHandle, tableCtrl, -1, 6, VAL_CELL_STRING);
FillTableCellRange (panelHandle, tableCtrl, MakeRect (1, 1, 3, 3), "hello!");
To get the values from a range of cells, use GetTableCellRangeVals.
To set and get the values of a range of cells, all cells in the range that you specify must be of the same cell type: VAL_CELL_NUMERIC, VAL_CELL_PICTURE, or VAL_TEXT_CELL_TYPE. Cells of type VAL_TEXT_CELL_TYPE are VAL_CELL_STRING, VAL_CELL_BUTTON, VAL_CELL_RING, and VAL_CELL_COMBO_BOX. If the type is VAL_CELL_NUMERIC, the cells in the range you specify also must have the same data type.
Specifying Default Values for Cells
When you insert new rows and columns in the table, the new cells are created with an initial set of attributes. Depending on how you are using the table, you might want the initial state of new cells to match the state of its neighboring cells in the same column, its neighboring cells in the same row, or neither. The table attribute ATTR_TABLE_MODE determines how new cells inherit their initial, default set of attributes: from their parent row, their parent column, or the table itself.
/* Inherit attributes from row. In the following code, the row preserves the attribute value as a "master" to be used as the initial value of the corresponding attribute on any new cells you create for that row. */
SetTableRowAttribute (panelHandle, tableCtrl, -1, ATTR_TEXT_BOLD, 1);
SetCtrlAttribute (panelHandle, tableCtrl, ATTR_TABLE_MODE, VAL_ROW);
/* Inherit attributes from column. In the preceding code, the column preserves the attribute value as a "master" to be used as the initial value of the corresponding attribute on any new cells you create for that column. */
SetTableColumnAttribute (panelHandle, tableCtrl, -1, ATTR_TEXT_BOLD, 1);
SetCtrlAttribute (panelHandle, tableCtrl, ATTR_TABLE_MODE, VAL_COLUMN);
/* Inherit attributes from table. In the following code, cell attributes set on the table itself are used on new cells. */
SetCtrlAttribute (panelHandle, tableCtrl, ATTR_TEXT_BOLD, 1);
SetCtrlAttribute (panelHandle, tableCtrl, ATTR_TABLE_MODE, VAL_GRID);
Specifying the Active Cell or Range of Cells
Call SetActiveTableCell to specify an active cell.
int col, row;
GetCtrlVal (panelHandle, PANEL_XPOINT, &col);
GetCtrlVal (panelHandle, PANEL_YPOINT, &row);
SetActiveTableCell (panelHandle, tableCtrl, MakePoint (col, row));
To select a range of cells, call SetTableSelection, which makes the top-left cell in the selection the active cell.
int top, left, width, height;
GetCtrlVal (panelHandle, PANEL_TOP, &top);
GetCtrlVal (panelHandle, PANEL_LEFT, &left);
GetCtrlVal (panelHandle, PANEL_WIDTH, &width);
GetCtrlVal (panelHandle, PANEL_HEIGHT, &height);
SetTableSelection (panelHandle, tableCtrl, MakeRect (top, left, height, width));
![]() |
Note The table selection is distinct from the active cell, and whereas there always exists an active cell (that is, the cell holding the keyboard focus), the selection consists of a rectangular cell range that can be empty. The only relationship between the active cell and the selection is that, if the selection is non-empty, the active cell is always contained within the selection. |
Customizing Table Cells
Call SetTableCellAttribute and SetTableCellRangeAttribute to customize table cells. Cell attributes can be specific to a given cell type, or they can apply regardless of cell type. Essentially any attribute that you can set on a numeric control, a text box control, or a picture control, you also can set on a table cell.
SetTableCellAttribute (panelHandle, tableCtrl, numCellPoint, ATTR_PRECISION, 4);
SetTableCellAttribute (panelHandle, tableCtrl, picCellPoint, ATTR_FIT_MODE, VAL_PICT_CENTER);
SetTableCellRangeAttribute (panelHandle, tableCtrl, MakeRect (1, 1, 3, 3), ATTR_CELL_DIMMED, 1);
Customizing Table Rows and Columns
Set row and column attributes using SetTableRowAttribute and SetTableColumnAttribute. Any attribute that you can set using SetTableCellAttribute or SetTableCellRangeAttribute also can be set as a row, column or table attribute, using SetTableRowAttribute, SetTableColumnAttribute, or SetCtrlAttribute, respectively.
SetTableColumnAttribute (panelHandle, tableCtrl, 4, ATTR_USE_LABEL_TEXT, 1);
SetTableColumnAttribute (panelHandle, tableCtrl, 4, ATTR_LABEL_TEXT, "Test");
SetTableRowAttribute (panelHandle, tableCtrl, 3, ATTR_ROW_HEIGHT, 30);
Obtaining the Number of Rows and Columns
int numCols, numRows;
GetNumTableColumns (panelHandle, tableCtrl, &numCols);
GetNumTableRows (panelHandle, tableCtrl, &numRows);
Copying and Pasting Data
Copy one or more cells to the clipboard using ClipboardPutTableVals.
Rect selectedRange;
GetTableSelection (panelHandle, tableCtrl, &selectedRange);
ClipboardPutTableVals (panelHandle, tableCtrl, selectedRange);
When the data appears in the system clipboard the <Tab> ASCII character separates the data of each cell, and the linefeed ASCII character, <LF>, separates the data of each row:
![]() | ![]() |
Copied cells | Pasted values |
LabWindows/CVI skips picture cells when it copies cells to the clipboard, with the following exception: if you pass a range consisting of a single picture cell to ClipboardPutTableVals, then the image contents of the picture cell are placed in the system clipboard as a bitmap image. LabWindows/CVI does not copy or paste values in combo box and ring cells.
You can paste the contents of the system clipboard into a table control using ClipboardGetTableVals. LabWindows/CVI assumes that the <Tab> ASCII character separates the data that corresponds to each cell, and that the linefeed ASCII character, <LF>, separates the data that corresponds to each row.
When the data in the clipboard includes an empty cell or cells, the paste operation makes no change to the corresponding cell or cells in the table that receives the new data. Similarly, when the data in the clipboard includes cells that contain data that cannot be converted to a valid number, the paste operation does not change to the corresponding cell or cells in the table that receives the new data.
If there is a bitmap image in the system clipboard and you want to paste it into a picture cell, pass a cell range containing only that cell to ClipboardGetTableVals.
Obtaining and Deleting the Values of Cell Ring Items
Ring and combo box cells contain lists of values that the end user can select from. When you set the value of a ring cell, the value that you set must already exist in this list.
/* Obtain the value and index of the table cell ring selected. */
int matchIdx, cellLen;
char *cellVal;
GetTableCellValLength (panelHandle, tableCtrl, ringCellPoint, &cellLen);
cellVal = malloc (sizeof (char) * (cellLen + 1));
GetTableCellVal (panelHandle, tableCtrl, ringCellPoint, cellVal);
GetTableCellRingIndexFromValue (panelHandle, tableCtrl, 0, ringCellPoint, &matchIdx, cellVal);
/* Insert items into a range of combo box cells. */
InsertTableColumns (panelHandle, tableCtrl, -1, 1, VAL_CELL_COMBO_BOX);
InsertTableCellRangeRingItem (panelHandle, tableCtrl, MakeRect (1, 4, 6, 1), -1, "Run");
InsertTableCellRangeRingItem (panelHandle, tableCtrl, MakeRect (1, 4, 6, 1), -1, "Stop");
InsertTableCellRangeRingItem (panelHandle, tableCtrl, MakeRect (1, 4, 6, 1), -1, "Delete");
/* Delete an item from a table cell ring. */
DeleteTableCellRingItems (panelHandle, tableCtrl, MakePoint (1, 4), 1, 1);
/* Delete an item from a range of cells. */
DeleteTableCellRangeRingItems (panelHandle, tableCtrl, MakeRect (1, 4, 6, 1), 2, 1);
Specifying Range Checking for Numeric Cells
SetTableCellRangeAttribute (panelHandle, tableCtrl, VAL_TABLE_ENTIRE_RANGE, ATTR_CHECK_RANGE, VAL_NOTIFY);
SetTableCellRangeAttribute (panelHandle, tableCtrl, VAL_TABLE_ENTIRE_RANGE, ATTR_MAX_VALUE, 75);
Searching for Values
Searching for a Cell Value
To search for a value in table cells, call GetTableCellFromValue.
/* Locate a specified cell value anywhere in the table. This example searches only cells that contain numeric data. */
Point foundCell;
int numToSearch;
GetCtrlVal (panelHandle, PANEL_SEARCHNUM, &numToSearch);
GetTableCellFromValue (panelHandle, tableCtrl, MakePoint (1, 1), VAL_TABLE_ENTIRE_RANGE, &foundCell, VAL_ROW_MAJOR, VAL_CELL_NUMERIC, VAL_INTEGER, numToSearch);
SetActiveTableCell (panelHandle, tableCtrl, foundCell);
The cellType parameter of the GetTableCellFromValue function specifies the cell type to search. If you search through combo box or ring cells, GetTableCellFromValue also searches through the item list of the ring and combo box cells. If you want to ignore these values, compare the string to the value returned by GetTableCellVal.
int currentValLength, wordLength, int result;
char *wordToSearch = 0, *currentVal = 0;
Point foundWord;
GetCtrlAttribute (panelHandle, PANEL_WORDSEARCH, ATTR_STRING_TEXT_LENGTH, &wordLength);
wordToSearch = malloc ((wordLength + 1) * sizeof (char));
GetCtrlVal (panelHandle, PANEL_WORDSEARCH, wordToSearch);
GetTableCellFromValue (panelHandle, PANEL_TABLE, MakePoint (1, 1), VAL_TABLE_ENTIRE_RANGE, &foundWord, VAL_ROW_MAJOR, VAL_CELL_RING, VAL_CHAR, wordToSearch);
GetTableCellValLength (panelHandle, PANEL_TABLE, foundWord, currentValLength);
currentVal = malloc ((currentValLength + 1) * sizeof (char));
GetTableCellVal (panelHandle, PANEL_TABLE, foundWord, currentVal);
result = strcmp (wordToSearch, currentVal);
SetCtrlVal (panelHandle, PANEL_NUMERIC, result);
if (result == 0) {
SetTableCellAttribute (panelHandle, PANEL_TABLE, foundWord, ATTR_TEXT_COLOR, VAL_RED); } else
{
MessagePopup ("Not found", "No match");
}
Searching for a Row Label
The GetTableRowFromLabel function searches for row labels that you specify using the ATTR_LABEL_TEXT attribute.
/* Locate a table row. */
int foundRow, int rowSearch;
char *rowVal;
SetTableRowAttribute (panelHandle, tableCtrl, -1, ATTR_USE_LABEL_TEXT, 1);
SetTableRowAttribute (panelHandle, tableCtrl, 1, ATTR_LABEL_TEXT, "Acme Corp.");
SetTableRowAttribute (panelHandle, tableCtrl, 2, ATTR_LABEL_TEXT, "Hillside");
SetTableRowAttribute (panelHandle, tableCtrl, 3, ATTR_LABEL_TEXT, "C Labs");
SetTableRowAttribute (panelHandle, tableCtrl, 4, ATTR_LABEL_TEXT, "Consolidated");
SetTableRowAttribute (panelHandle, tableCtrl, 5, ATTR_LABEL_TEXT, "State Works");
SetTableRowAttribute (panelHandle, tableCtrl, 6, ATTR_LABEL_TEXT, "Skyview");
GetCtrlAttribute (panelHandle, PANEL_ROWSEARCH, ATTR_STRING_TEXT_LENGTH, &rowSearch);
rowVal = malloc (sizeof(char) * (rowSearch + 1));
GetCtrlVal (panelHandle, PANEL_ROWSEARCH, rowVal);
GetTableRowFromLabel (panelHandle, tableCtrl, 1, &foundRow, rowVal, 1);
SetTableCellRangeAttribute (panelHandle, tableCtrl, VAL_TABLE_ROW_RANGE (foundRow), ATTR_TEXT_BOLD, 1);
Searching for a Column Label
The GetTableColumnFromLabel function searches for row labels that you specify using the ATTR_LABEL_TEXT attribute.
/* Locate a table column. */
int colSearch, foundCol;
char *colVal;
SetTableColumnAttribute (panelHandle, tableCtrl, -1, ATTR_USE_LABEL_TEXT, 1);
SetTableColumnAttribute (panelHandle, tableCtrl, 1, ATTR_LABEL_TEXT, "Q1 orders");
SetTableColumnAttribute (panelHandle, tableCtrl, 2, ATTR_LABEL_TEXT, "Q2 orders");
SetTableColumnAttribute (panelHandle, tableCtrl, 3, ATTR_LABEL_TEXT, "Q3 orders");
GetCtrlAttribute (panelHandle, PANEL_COLSEARCH, ATTR_STRING_TEXT_LENGTH, &colSearch);
colVal = malloc (sizeof(char) * (colSearch + 1));
GetCtrlVal (panelHandle, PANEL_COLSEARCH, colVal);
GetTableColumnFromLabel (panelHandle, tableCtrl, 1, &foundCol, colVal, 1);
SetTableCellRangeAttribute (panelHandle, tableCtrl, VAL_TABLE_COLUMN_RANGE (foundCol), ATTR_TEXT_BOLD, 1);
Sorting Values
Call SortTableCells to sort a range of cells using the data in one of the rows or columns as the sort key.
Point activeCell;
Rect selectedRange;
GetTableSelection (panelHandle, tableCtrl, &selectedRange);
GetActiveTableCell (panelHandle, tableCtrl, &activeCell);
SortTableCells (panelHandle, tableCtrl, selectedRange, VAL_ROW_MAJOR, activeCell.x, 1, NULL, 0);
You can pass in a callback function that LabWindows/CVI calls whenever it must compare the values of any two cells, thus allowing you to customize the sort.
Customizing the Context Menu
The table control includes a context menu by default.
/* Remove and add additional built-in items from the context menu. */
HideBuiltInCtrlMenuItem (panelHandle, tableCtrl, VAL_GOTO);
ShowBuiltInCtrlMenuItem (panelHandle, tableCtrl, VAL_FIND_NEXT, -1);
ShowBuiltInCtrlMenuItem (panelHandle, tableCtrl, VAL_FIND_PREV, -1);
/* Add your own items to the context menu. */
void CVICALLBACK CustomMenu (int panelHandle, int controlID, int MenuItemID, void *callbackData);
. . .
NewCtrlMenuItem (panelHandle, tablectrl, "My Menu Item", -1, CustomMenu, 0);
. . .
void CVICALLBACK CustomMenu (int panelHandle, int controlID, int MenuItemID, void *callbackData)
{
MessagePopup ("Table Control Menu", "You selected a custom item");
}
You also can use control menu attributes to configure context menus. Call GetCtrlMenuAttribute and SetCtrlMenuAttribute to get and set these attributes.
Optimizing Performance
To optimize performance and minimize the number of times that a table draws, use the SetTableCellRangeVals and FillTableCellRange functions. These functions set the values of multiple table cells, so they are more efficient than calling SetTableCellVal multiple times.
To minimize the number of times that a table draws, you can hide the table prior to calling SetTableCellRangeVals or SetTableCellVal. To hide the table, set ATTR_VISIBLE to 0. After you set the table cell values, set ATTR_VISIBLE to 1.
/* Minimize number of times the table draws. */
SetCtrlAttribute (panelHandle, PANEL_TABLE, ATTR_VISIBLE, 0);
SetTableCellRangeVals (panelHandle, PANEL_TABLE, MakeRect (1, 1, 25, 25), tableVals, VAL_ROW_MAJOR);
SetCtrlAttribute (panelHandle, PANEL_TABLE, ATTR_VISIBLE, 1);
Also, ensure that you do not call ProcessDrawEvents or ProcessSystemEvents while you update the table cell values.
Binding to a DataSocket source
(Linux) Data binding is not supported.
Controls can have only one DataSocket connection. You must specify whether the access mode is READ mode or WRITE mode:
- READ mode—The control gets data from the DataSocket source. In READ mode, the value of the table control is updated automatically when the value changes at the source.
- WRITE mode—The control transfers data to the DataSocket source. In WRITE mode, the value at the DataSocket source is updated automatically when the value of the table control changes.
You must enable the DataSocket option in the Edit Installer dialog box Drivers & ComponentsDrivers & Components tab if your applications use data binding.
Binding to a DataSocket Source in the User Interface Editor
Complete the following steps to bind a network variable to a table control.
- In the Edit Table dialog box, click the Insert Row Above and Insert Column After buttons.
- Click the DataSocket Binding button.
- Click the browse button to the right of the Server text box in the DataSocket Binding dialog box.
- Select the network variable you want to bind and click the OK button.
- Select whether you want to read or write data in the Connection Type option.
- Click the OK button.
Binding to a DataSocket Source Programmatically
Use DSBindCtrl to bind a table control to a DataSocket source. The data type of the control must match the data type in the DataSocket source.
DSBindCtrl (panelHandle, PANEL_TABLE, "dstp://localhost/samplenum", VAL_DS_READ, &dsHandle, &dsError);
Use DSBindTableCellRange to bind a range of table cells to a DataSocket source. Table cells must be of the same cell type and data type, and picture cells cannot be part of the range. Data is sent to and received from the DataSocket source as a 2D array of data. Data also can be received from the DataSocket source as a 1D array and is written to the table in row-major order.
Use DSUnbind to disconnect the strip chart control from the DataSocket source.
You must enable the DataSocket option in the Edit Installer dialog box Drivers & ComponentsDrivers & Components tab if your applications use data binding.
Related Topics
In This Section
- Creating a Table Control
- Adding Rows, Columns, and Cells to a Table
- Deleting Rows and Columns
- Specifying the Type of Data a Cell Can Contain
- Specifying Default Values for Cells
- Specifying the Active Cell or Range of Cells
- Customizing Table Cells
- Customizing Table Rows and Columns
- Obtaining the Number of Rows and Columns
- Copying and Pasting Data
- Obtaining and Deleting the Values of Cell Ring Items
- Specifying Range Checking for Numeric Cells
- Searching for Values
- Sorting Values
- Customizing the Context Menu
- Optimizing Performance
- Binding to a DataSocket source