Class
DesktopTable
Table, Grid
Description
The scrollable DesktopTable control displays one or more columns of information.
Rows can be held by the table itself or supplied by a TableDataSource, in which case the table keeps no copy of the data and asks for the visible cells only.
Properties
Name |
Type |
Read-Only |
Shared |
|---|---|---|---|
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
|||
✓ |
Methods
Name |
Parameters |
Returns |
Shared |
|---|---|---|---|
FileType As String |
|||
Type As String |
|||
rows As RowSet |
|||
items() As String |
|||
items(,) As String |
|||
ParamArray item As String |
|||
count As Integer |
|||
rows As RowSet |
|||
items() As String |
|||
items(,) As String |
|||
ParamArray item As String |
|||
count As Integer |
|||
header As String = "" |
|||
items() As String |
|||
ParamArray item As String |
|||
receiver As ListSelectionNotificationReceiver |
|||
items() As String |
|||
ParamArray item As String |
|||
row As Integer, column As Integer, Assigns value As DesktopTable.Alignments |
|||
row As Integer, column As Integer, Assigns value As ColorGroup |
|||
row As Integer, column As Integer, Assigns value As DesktopCheckBox.VisualStates |
|||
row As Integer, column As Integer, ByRef anchorRow As Integer, ByRef anchorColumn As Integer, ByRef rowSpan As Integer, ByRef columnSpan As Integer |
|||
row As Integer, column As Integer = 0, Assigns value As String |
|||
row As Integer, column As Integer, Assigns value As DesktopTable.CellTypes |
|||
column As Integer |
|||
column As Integer, Assigns value As DesktopTable.Alignments |
|||
column As Integer |
|||
column As Integer |
|||
column As Integer, Assigns value As DesktopTableColumn |
|||
index As Integer |
|||
column As Integer |
|||
column As Integer, Assigns value As DesktopTable.SortDirections |
|||
column As Integer |
|||
column As Integer, Assigns value As DesktopTable.SortTypes |
|||
column As Integer |
|||
column As Integer |
|||
column As Integer, Assigns value As DesktopTable.CellTypes |
|||
index As Integer |
|||
row As Integer, column As Integer, rowSpan As Integer, columnSpan As Integer |
|||
file As FolderItem, delimiter As String = ",", importHeaders As Boolean = True |
|||
column As Integer |
|||
x As Integer, y As Integer, width As Integer, height As Integer, immediately As Boolean = False |
|||
index As Integer |
|||
receiver As ListSelectionNotificationReceiver |
|||
index As Integer |
|||
identifier As String |
|||
row As Integer |
|||
row As Integer |
|||
row As Integer |
|||
row As Integer |
|||
container As DesktopContainer |
|||
row As Integer |
|||
index As Integer |
|||
index As Integer |
|||
row As Integer |
|||
file As FolderItem, delimiter As String = ",", exportHeaders As Boolean = True |
|||
row As Integer |
|||
Events
Name |
Parameters |
Returns |
|---|---|---|
row As Integer |
||
row As Integer |
||
row As Integer, column As Integer, x As Integer, y As Integer |
||
column As Integer |
||
column As Integer |
||
base As DesktopMenuItem, x As Integer, y As Integer |
||
row As Integer, column As Integer, container As DesktopContainer |
||
selectedItem As DesktopMenuItem |
||
obj As DragItem, action As DragItem.Types |
||
obj As DragItem, action As DragItem.Types |
||
x As Integer, y As Integer, obj As DragItem, action As DragItem.Types |
||
x As Integer, y As Integer, obj As DragItem, action As Integer, ByRef row As Integer, ByRef parentRow As Integer, ByRef location As DesktopTable.DropLocations |
||
obj As DragItem, action As DragItem.Types |
||
x As Integer, y As Integer, obj As DragItem, action As Integer, row As Integer, parentRow As Integer, location As DesktopTable.DropLocations |
||
key As String |
||
key As String |
||
x As Integer, y As Integer, deltaX As Integer, deltaY As Integer |
||
g As Graphics |
||
g As Graphics, row As Integer, column As Integer, x As Integer, y As Integer |
||
g As Graphics, row As Integer, ByRef x As Integer, ByRef y As Integer, ByRef width As Integer, ByRef height As Integer |
||
g As Graphics, column As Integer, x As Integer, y As Integer |
||
g As Graphics, row As Integer, action As DesktopTableRowAction, pressed As Boolean |
||
g As Graphics, column As Integer, ByRef x As Integer, ByRef y As Integer, ByRef width As Integer, ByRef height As Integer |
||
row As Integer, action As DesktopTableRowAction |
||
row As Integer |
||
row1 As Integer, row2 As Integer, column As Integer, ByRef result As Integer |
||
row As Integer |
||
Constants
These constants are designed to be used with some DesktopTable methods to make code more readable.
Name
Description
AllColumns
Sentinel for 'every column' in cell and column setters.
AllRows
Sentinel for 'every row' in cell setters.
NoSelection
Returned by
SelectedRowIndexwhen nothing is selected.
Enumerations
DesktopTable.Alignments
Alignments
Used to indicate how the content of a cell or column is aligned.
Enum
Description
Default
The platform's default alignment, left in a left-to-right layout.
Left
The value is left-justified.
Center
The value is centred.
Right
The value is right-justified.
Decimal
The value is aligned on its decimal separator.
DesktopTable.CellTypes
CellTypes
Used to indicate what a cell contains and whether the user can edit it.
Enum
Description
Default
The cell uses the type of its column.
Normal
A cell the user cannot edit directly.
CheckBox
The cell shows a native checkbox.
TextField
The cell can be edited in a single-line inline editor.
TextArea
The cell can be edited in a multi-line inline editor.
ProgressBar
The cell shows a native progress bar; the value comes from CellProgressBarValueAt.
Container
The cell shows a DesktopContainer, supplied by the ContainerAt event.
DesktopTable.DropLocations
DropLocations
Used to indicate where on the table an object was dropped.
Enum
Description
OnRow
The drop happens on the row itself.
AfterRow
The drop happens between rows, after the row given. -1 inserts above all rows.
AfterAllRows
The drop happens after the last row.
OnControl
The drop happens on the control as a whole, not on a particular row.
DesktopTable.GridLineStyles
GridLineStyles
Used to indicate which grid lines are drawn.
Enum
Description
None
No grid lines. This is the default.
Horizontal
Horizontal grid lines only.
Vertical
Vertical grid lines only.
Both
Both horizontal and vertical grid lines.
DesktopTable.RowSelectionTypes
RowSelectionTypes
Used to indicate whether one or more rows can be selected.
Enum
Description
Single
Only one row can be selected at a time.
Multiple
Any number of rows can be selected at the same time.
DesktopTable.SortDirections
SortDirections
Used to indicate whether a column sorts ascending, descending or not at all.
Enum
Description
Descending
The rows are sorted in reverse order.
None
The column is not sorted and its header shows no sort indicator.
Ascending
The rows are sorted in standard order.
DesktopTable.SortTypes
SortTypes
Used to indicate whether the user can sort a column by its header.
Enum
Description
Sortable
The column header sorts the table when it is clicked.
NotSortable
The column header does not sort the table.
Property descriptions
DesktopTable.Active
Active As Boolean
Indicates whether the control is active.
Active is False when the control's window is not in the foreground. When a DesktopWindow is deactivated, its controls are automatically deactivated unless AllowAutoDeactivate is set to False.
This property is read-only.
This example reads the property:
Var value As Boolean = Table1.Active
DesktopTable.ActiveTextControl
ActiveTextControl As DesktopTextControl
The live inline editor (DesktopTextField or DesktopTextArea), or Nil when no cell is being edited.
This property is read-only.
This example reads the live inline editor (DesktopTextField or DesktopTextArea), or Nil when no cell is being edited:
Var value As DesktopTextControl = Table1.ActiveTextControl
DesktopTable.AllowAutoDeactivate
AllowAutoDeactivate As Boolean
Determines whether the control should be deactivated (on macOS) when the parent window is deactivated. The default is True.
This example sets the property:
Table1.AllowAutoDeactivate = True
DesktopTable.AllowAutoHideScrollbars
AllowAutoHideScrollbars As Boolean
Lets the scrollbars hide themselves when the content fits. With False the scrollbars stay visible even when everything fits. On macOS the system setting for overlay scrollbars decides how they are drawn; the table follows a change of that setting while it is running.
This example lets the scrollbars hide themselves when the content fits:
Table1.AllowAutoHideScrollbars = True
DesktopTable.AllowColumnReordering
AllowColumnReordering As Boolean
Columns can be dragged by their header. Allows reordering columns by dragging the column headers. The user drags a column by its header and an insertion marker shows where it will land. The move is reported by ColumnReordering before and ColumnReordered after it, and the column index changes with it. With frozen columns, reordering is confined to the scrolling middle band.
This example sets the columns can be dragged by their header:
Table1.AllowColumnReordering = True
DesktopTable.AllowExpandableRows
AllowExpandableRows As Boolean
Reserves space for disclosure widgets and enables the hierarchy. Rows added with AddExpandableRow then show a disclosure widget, and every row is indented by its RowDepthAt. Opening and closing a row fires RowExpanded and RowCollapsed.
This example sets the reserves space for disclosure widgets and enables the hierarchy:
Table1.AllowExpandableRows = True
DesktopTable.AllowFocus
AllowFocus As Boolean
If True, the canvas will be included in the Tab order and can accept the focus. The FocusReceived and FocusLost events are called at the appropriate times.
This code enables the AllowFocus property. It is in the Opening event of the control.
Me.AllowFocus = True
DesktopTable.AllowFocusRing
AllowFocusRing As Boolean
If True, the DesktopTable indicates that it has the focus with a ring around its border; if False, the appearance of the object does not change when it has the focus.
Setting this property to True has no effect on Windows or Linux. The default is True.
This code turns AllowFocusRing off.
Me.AllowFocusRing = False
DesktopTable.AllowResizableColumns
AllowResizableColumns As Boolean
Column widths can be dragged in the header. The pointer changes shape over a column divider, and dragging it changes that column's width expression. ColumnResizing fires while dragging, ColumnResized once. A single column can be locked against resizing with ColumnAttributesAt and its
UserResizableproperty.This example sets the column widths can be dragged in the header:
Table1.AllowResizableColumns = True
DesktopTable.AllowResizableRows
AllowResizableRows As Boolean
Row heights can be dragged. Allows changing the row height with the mouse (handle at the. The user drags the lower edge of a row in the same way a column divider is dragged, which sets that row's RowHeightAt.
This example sets the row heights can be dragged:
Table1.AllowResizableRows = True
DesktopTable.AllowRowAnimation
AllowRowAnimation As Boolean
A row added with AddRow, AddRowAt or AddExpandableRow fades and slides in, and one removed with RemoveRowAt fades and slides out. The default is True.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
This example turns the animation off:
Table1.AllowRowAnimation = False
DesktopTable.AllowRowDragging
AllowRowDragging As Boolean
Rows can be dragged out of the table. Allows dragging rows outward (DragRow event).
This example sets the rows can be dragged out of the table:
Table1.AllowRowDragging = True
DesktopTable.AllowRowReordering
AllowRowReordering As Boolean
Rows can be reordered by dragging. Allows reordering rows with the mouse (DragReorderRows event).
This example sets the rows can be reordered by dragging:
Table1.AllowRowReordering = True
DesktopTable.AllowTabs
AllowTabs As Boolean
If True and AllowFocus is True, then pressing Tab triggers the KeyDown event for processing. The default is False.
If False, pressing the Tab key does not trigger the KeyDown event; pressing Tab triggers the FocusLost Event and selects the next object in the window that can accept the focus.
The following turns on AllowTabs.
Me.AllowTabs = True
DesktopTable.AllowTabStop
AllowTabStop As Boolean
If True, the control is in the Tab Order and accepts the focus when the user tabs into it. The default is True. If False, the user cannot tab into it to give it the focus. However, the control can gain the focus by other means, such as the user's clicking on it or by setting the focus in code.
This example removes the control from the Tab Order:
Me.AllowTabStop = False
DesktopTable.AlternatingRowColor
AlternatingRowColor As ColorGroup
Background color of every second row while HasAlternatingRowColors is True. Nil (the default) uses the tint the platform itself uses for lists: on macOS the system's second content background color, on Windows and Linux a nearly transparent black in light mode and a nearly transparent white in dark mode, so whatever lies behind the table still shows through. A table with HasTranslucentBackground uses the transparent mix on macOS too, because the system color is opaque in light mode and would paint the blur away on every second row.
This example tints every second row in the company's pale gray instead of the system color:
Table1.AlternatingRowColor = New ColorGroup(&cF2F4F7, &c2B2F33) Table1.HasAlternatingRowColors = True
DesktopTable.Bold
Bold As Boolean
Base font style for the whole table. It applies to every cell and to the column headers, unless a cell overrides it with CellBoldAt.
This example sets the base font style for the whole table:
Table1.Bold = True
DesktopTable.BottomInset
BottomInset As Double
Free, non-clickable area after the last row, in points; enlarges the scrollable content. Use it to keep the last row clear of something drawn over the lower edge, or simply to let the content scroll past the end.
This example sets the free, non-clickable area after the last row, in points; enlarges the scrollable content:
Table1.BottomInset = 1.0
DesktopTable.CellContainerPadding
CellContainerPadding As Double
Gap in points between the edge of a cell and the container shown in it, on all four sides. The default is 0.
It applies to every cell of type Container: the container is given what is left of the cell, so a padding of 4 makes it 8 points narrower and 8 points shorter than the cell itself.
This example keeps the containers clear of the grid lines:
Table1.CellContainerPadding = 4
DesktopTable.ColumnCount
ColumnCount As Integer
Number of columns. The original clamps at 256; thanks to virtualization. Raising it appends empty columns, lowering it removes the columns on the right including their cell content. The column count is not limited to 256, and the drawing cost depends on the columns actually visible, not on this number.
This example sets the number of columns:
Table1.ColumnCount = 3
DesktopTable.ColumnWidths
ColumnWidths As String
Comma-separated width expressions (points,
*shares, or percentages). Each value applies to the column at the same position: a point value (120), a percentage (25%) or a share of the remaining width (*,2*). An unusable expression raises an UnsupportedFormatException. Individual columns can be set through ColumnAttributesAt instead.This example sets the comma-separated width expressions:
Table1.ColumnWidths = "120,*,80"
DesktopTable.ContainerCacheSize
ContainerCacheSize As Integer
How many containers the table keeps for reuse beyond the ones in use. The default is 24.
A cell that scrolls out of view hands its container to this pool, and ReusableContainer gives it to the next cell that asks for one of the same kind. 0 switches the reuse off: every cell then builds its own container, and ContainerRemovedAt reports each one the table has finished with.
This example switches the reuse off:
Table1.ContainerCacheSize = 0
DesktopTable.Content
Content As String
Whole content - rows separated by EndOfLine, cells by
Tab. Reading it returns the whole table, writing it replaces every row. It is the text form the inline editor and CellTextAt also use, so a value containing a Tab or a line break changes the shape of the result.This example sets the whole content - rows separated by EndOfLine, cells by Tab:
Table1.Content = "Anna" + Chr(9) + "Berlin"
DesktopTable.DataSource
DataSource As TableDataSource
Virtual data source; Nil selects in-memory mode. With a data source assigned the table keeps no rows of its own: it asks the source for RowCount and for the text of the cells it is about to draw. Everything else - selection, row heights, cell styles, tags - stays with the table, kept per row index. After the data behind the source changed, call ReloadFromDataSource.
This example sets the virtual data source; Nil selects in-memory mode:
Table1.DataSource = myTableDataSource
DesktopTable.DefaultRowHeight
DefaultRowHeight As Integer
Row height in points;
-1derives it from the font. It applies to every row that has no RowHeightAt of its own. Leaving all rows at the default is also the fastest case: the offset of a row is then a single multiplication, with no per-row data at all.This example sets the row height in points; -1 derives it from the font:
Table1.DefaultRowHeight = 24
DesktopTable.DropIndicatorVisible
DropIndicatorVisible As Boolean
Shows the insertion indicator during a drop. It only changes what is drawn. The drag events fire either way.
This example shows the insertion indicator during a drop:
Table1.DropIndicatorVisible = True
DesktopTable.Enabled
Enabled As Boolean
Determines if the control should be enabled when the owning window is opened.
A disabled control cannot be clicked and cannot receive the focus.
This example disables the control.
Me.Enabled = False
DesktopTable.FontName
FontName As String
Base font. It applies to every cell and to the column headers. Besides an installed font you can use the metafonts
SystemandSmallSystem.This example sets the base font:
Table1.FontName = "Helvetica"
DesktopTable.FontSize
FontSize As Single
Base font size. A value of 0 uses the size that suits the platform. The row height follows the font when DefaultRowHeight is left at -1.
This example sets the base font size:
Table1.FontSize = 14
DesktopTable.FontUnit
FontUnit As FontUnits
DesktopTable.FrozenColumns
FrozenColumns As DesktopTableFrozenColumns
Always the same instance; set
.Left/.Rightto pin columns. Set itsLeftandRightto pin that many columns to the edges while the columns in between scroll. In a right-to-left layout the leading edge is on the right.This property is read-only.
This example reads the always the same instance; set .Left / .Right to pin columns:
Var value As DesktopTableFrozenColumns = Table1.FrozenColumns
DesktopTable.FrozenRows
FrozenRows As DesktopTableFrozenRows
Always the same instance; set
.Top/.Bottomto pin rows. Set itsTopandBottomto pin that many rows below the header and above the lower edge, which is how a totals row is kept in view.This property is read-only.
This example reads the always the same instance; set .Top / .Bottom to pin rows:
Var value As DesktopTableFrozenRows = Table1.FrozenRows
DesktopTable.GridColor
GridColor As ColorGroup
DesktopTable.GridLineStyle
GridLineStyle As DesktopTable.GridLineStyles
Which grid lines are drawn. Grid lines are drawn between cells, never through a merged cell, and they follow the column widths, so a hidden column adds no line of its own.
This example sets the which grid lines are drawn:
Table1.GridLineStyle = DesktopTable.GridLineStyles.Both
DesktopTable.Handle
Handle As Ptr
Returns a handle to the control.
This property is read-only.
For interfacing with Mac APIs using Declares, DesktopControl.Handle returns NSViews (except for DesktopToolbar).
On Windows returns the HWND of the control.
On Linux it returns a GtkWidget.
The following gets a handle to the control.
Var p As Ptr = Me.Handle
DesktopTable.HasAlternatingRowColors
HasAlternatingRowColors As Boolean
Draws every second row in AlternatingRowColor, which makes a wide row easier to follow across its columns. The default is False. Row 0 keeps the plain background, the stripes cover the full width of a row including frozen columns, the area past the last column and the action strips of a swiped row, and the pattern keeps running below the last row.
The stripe is drawn underneath everything else the row paints, so a PaintCellBackground handler that returns True, the selection highlight and the grid lines all keep their usual appearance.
This example turns the stripes on for a table with many columns:
Table1.HasAlternatingRowColors = True
DesktopTable.HasBorder
HasBorder As Boolean
Draws the control border. The border is drawn by the platform, so it matches other framed controls.
This example draws the control border:
Table1.HasBorder = True
DesktopTable.HasColumnHeader
HasColumnHeader As Boolean
Shows the column header row. Turn the translucent header on/off together with the header. The header shows the text of ColumnHeaderAt, is drawn in the platform theme and is where the user clicks to sort, drags to resize and drags to reorder columns.
This example shows the column header row:
Table1.HasColumnHeader = True
DesktopTable.HasHorizontalScrollbar
HasHorizontalScrollbar As Boolean
Enables horizontal scrolling. The scrollbar only appears when the columns are wider than the table. The position is available as ScrollPositionX.
This example sets the enables horizontal scrolling:
Table1.HasHorizontalScrollbar = True
DesktopTable.HasTranslucentBackground
HasTranslucentBackground As Boolean
macOS only - places an
NSVisualEffectViewbehind the table. The inline editor of a TextField or TextArea cell is then drawn without a background of its own, so the translucency shows through while a cell is being edited.This example sets the macOS only - places an NSVisualEffectView behind the table:
Table1.HasTranslucentBackground = True
DesktopTable.HasTranslucentHeader
HasTranslucentHeader As Boolean
macOS only - translucent header; rows glide blurred beneath it.
This example sets the macOS only - translucent header; rows glide blurred beneath it:
Table1.HasTranslucentHeader = True
DesktopTable.HasVerticalScrollbar
HasVerticalScrollbar As Boolean
Enables vertical scrolling. The position is available as ScrollPosition.
This example sets the enables vertical scrolling:
Table1.HasVerticalScrollbar = True
DesktopTable.HeaderHeight
HeaderHeight As Integer
Header height in points. Height of the header row in points. It is the height of the header row only; the rows below are unaffected.
This example sets the header height in points:
Table1.HeaderHeight = 28
DesktopTable.HeadingIndex
HeadingIndex As Integer
Sets the sort column and the sort indicator in the header row. It is the column the indicator is shown for. The sort itself runs when Sort is called or the user clicks a sortable header.
This example sets the sort column and the sort indicator in the header row:
Table1.HeadingIndex = 0
DesktopTable.Height
Height As Integer
The height (in points) of the control.
This example sets the height of the control to 100:
Me.Height = 100
DesktopTable.Index
Index As Integer
If the control is used in a control set, this specifies the control's index in the set.
This example sets the property:
Table1.Index = 0
DesktopTable.InitialValue
InitialValue As String
Design-time content, applied when you start your app. Rows are separated by line breaks and cells by Tab. It is applied while the control opens, so code in the Opening event runs on top of it.
This example sets the design-time content, applied in Opening:
Table1.InitialValue = "Name" + Chr(9) + "City"
DesktopTable.Italic
Italic As Boolean
Base font style. It applies to every cell and to the column headers, unless a cell overrides it with CellItalicAt.
This example sets the base font style:
Table1.Italic = True
DesktopTable.LastAddedColumnIndex
LastAddedColumnIndex As Integer
Index of the most recently added column,
-1if none. Use it to address a column right after adding it, instead of counting positions yourself.This property is read-only.
This example reads the index of the most recently added column, -1 if none:
Var value As Integer = Table1.LastAddedColumnIndex
DesktopTable.LastAddedRowIndex
LastAddedRowIndex As Integer
Index of the most recently added row, NoSelection if none. Use it to fill the other cells of a row right after adding it.
This property is read-only.
This example reads the index of the most recently added row, NoSelection if none:
Var value As Integer = Table1.LastAddedRowIndex
DesktopTable.LastColumnIndex
LastColumnIndex As Integer
Index of the last column. It is one less than ColumnCount, and -1 while the table has no columns.
This property is read-only.
This example reads the index of the last column:
Var value As Integer = Table1.LastColumnIndex
DesktopTable.LastRowIndex
LastRowIndex As Integer
Index of the last row. It is one less than RowCount, and -1 while the table is empty.
This property is read-only.
This example reads the index of the last row:
Var value As Integer = Table1.LastRowIndex
DesktopTable.Left
Left As Integer
The distance from the left side of the control to the left side of its containing window or container.
The following example moves the control 100 points from the left side of the window:
Me.Left = 150
DesktopTable.LockBottom
LockBottom As Boolean
Determines whether the bottom edge of the control should stay at a set distance from the bottom edge of the parent control, if there is one, or the owning window.
This property can be set in the control's Inspector. The following example sets it in code.
Me.LockBottom = True
DesktopTable.LockLeft
LockLeft As Boolean
Determines whether the left edge of the control should stay at a set distance from the left edge of the parent control, if there is one, or the owning window.
LockLeft and Locktop default to True when you add a new control to a window. Existing controls will be altered only if LockRight and/or LockBottom are not set. LockLeft has no effect unless LockRight is True.
This property can be set in the control's Inspector. The following example sets it in code.
Me.LockLeft = True
DesktopTable.LockRight
LockRight As Boolean
Determines whether the right edge of the control should stay at a set distance from the right edge of the parent control, if there is one, or the owning window.
This property can be set in the control's Inspector. The following example sets it in code.
Me.LockRight = True
DesktopTable.LockTop
LockTop As Boolean
Determines whether the top edge of the control should stay at a set distance from the top edge of the parent control, if there is one, or the owning window.
LockTop and LockLeft default to True when you add a control to a window. Existing controls will be altered only if LockRight and/or LockBottom are not set. LockTop has no effect unless LockBottom is True.
This property can be set in the control's Inspector. The following example sets it in code.
Me.LockTop = True
DesktopTable.MouseCursor
MouseCursor As MouseCursor
The cursor to be displayed while the mouse is within the control and both the DesktopApplication and DesktopWindow class's MouseCursor properties are Nil.
If the DesktopApplication class's MouseCursor property is not Nil or the DesktopWindow's MouseCursor property is not Nil, then any control's MouseCursor property is ignored. You can use a cursor stored in the Cursors module. On macOS, you can also obtain a MouseCursor from a resource file.
This line in the Opening event of the control sets the default cursor to the finger pointer.
Me.MouseCursor = System.Cursors.FingerPointer
DesktopTable.Name
Name As String
The name of the control. Set the name of the control in the Inspector.
This property is read-only.
This example reads the property:
Var value As String = Table1.Name
DesktopTable.PanelIndex
PanelIndex As Integer
If the control has been placed on a DesktopTabPanel or DesktopPagePanel control, this is the panel (page/tab) that the control is on. If the control is not on a panel, it returns -1.
The first panel is numbered zero. If the control has been placed on a panel of a DesktopTabPanel or DesktopPagePanel control, it returns the panel number. If the control is not on a DesktopPagePanel or DesktopTabPanel, it returns -1. If you change the PanelIndex to a nonexistent panel, the control will disappear until you give it a PanelIndex value that corresponds to a panel that exists.
If you are looking to change the currently selected panel (page/tab), use DesktopPagePanel.SelectedPanelIndex.
This code displays the panel index of the control that is on the page.
MessageBox(Me.SelectedPanelIndex.ToString)
DesktopTable.Parent
Parent As Object
Used to get and set the control's parent control or window.
If the control is on the window, the Parent will be the Window. If the control is on the container, the Parent will be the container. If the control is completed enclosed by another control, the Parent will be that control.
If you do not want the enclosing control to be the parent, set the Parent property of that control to Nil to make it the Window.
If the parent control is somehow in another window, an InvalidParentException will occur.
The following example sets the parent of the control to the window.
Me.Parent = Nil
DesktopTable.RequiresSelection
RequiresSelection As Boolean
Keeps at least one row selected. True prevents the user from clearing the last selection. With True a click on empty space or on the selected row no longer clears the selection. It does not select a row by itself; that is up to your code.
This example keeps at least one row selected:
Table1.RequiresSelection = True
DesktopTable.RowCount
RowCount As Integer
Number of rows. In DataSource mode it is what the source reports, otherwise the number of rows the table holds itself.
This property is read-only.
This example reads the number of rows:
Var value As Integer = Table1.RowCount
DesktopTable.RowHeight
RowHeight As Integer
Resolved default row height in points. It is the height DefaultRowHeight resolves to, so it is a real measurement even when the height follows the font.
This property is read-only.
This example reads the resolved default row height in points:
Var value As Integer = Table1.RowHeight
DesktopTable.RowSelectionType
RowSelectionType As DesktopTable.RowSelectionTypes
Single or multiple selection. Single reduces a multiple selection to the bottom-most row. It decides how clicking, dragging and the arrow keys change the selection. Switching to Single while several rows are selected keeps the bottom-most one.
This example sets the single or multiple selection:
Table1.RowSelectionType = DesktopTable.RowSelectionTypes.Multiple
DesktopTable.Scope
Scope As Integer
Used to determine whether access to the control is Public (0) or Private (2). The default is Public.
This property is read-only.
Note
This is a designtime-only property and thus can only be set in the Inspector and is not accessible via code.
If the Scope of a control is set to Private, it cannot be accessed from outside its parent window.
This example reads the property:
Var value As Integer = Table1.Scope
DesktopTable.ScrollPosition
ScrollPosition As Integer
Index of the top-most visible row. Assigning it scrolls so that row becomes the top-most one, which is the same movement the vertical scrollbar makes.
This example sets the index of the top-most visible row:
Table1.ScrollPosition = 0
DesktopTable.ScrollPositionX
ScrollPositionX As Integer
Horizontal scroll offset in points. Horizontal scroll position in points. It is measured in points, not in columns, so it can stop in the middle of a column.
This example sets the horizontal scroll offset in points:
Table1.ScrollPositionX = 0
DesktopTable.SelectedRowCount
SelectedRowCount As Integer
Number of selected rows. It is kept as rows are selected and deselected, so it costs nothing to read even with many rows.
This property is read-only.
This example reads the number of selected rows:
Var value As Integer = Table1.SelectedRowCount
DesktopTable.SelectedRowIndex
SelectedRowIndex As Integer
Smallest selected row index, or
NoSelection. With several rows selected it is the topmost of them; assigning it selects that single row. Use RowSelectedAt to read or set the state of a particular row.This example sets the smallest selected row index, or NoSelection:
Table1.SelectedRowIndex = 0
DesktopTable.SelectedRowText
SelectedRowText As String
Text of column 0 of the selected row. Text (column 0) of the selected row. It is a shortcut for the first column of the selected row and follows the same rule as SelectedRowIndex when several rows are selected.
This property is read-only.
This example reads the text of column 0 of the selected row:
Var value As String = Table1.SelectedRowText
DesktopTable.SortingColumn
SortingColumn As Integer
Column used by Sort;
-1for none. Does not set a header indicator. It is the column Sort uses, together with the direction from ColumnSortDirectionAt. Set HeadingIndex as well to show the indicator in the header.This example sets the column used by Sort; -1 for none:
Table1.SortingColumn = 0
DesktopTable.TabIndex
TabIndex As Integer
The control's position in the Tab Order. The control with whose TabIndex is 0 will get the focus first.
On macOS, only controls where you enter data from the keyboard typically get the focus. In order to manually set focus to controls that don't allow keyboard entry, go to System Preferences, click on the Keyboard icon then on the Shortcuts tab and then check the Use keyboard navigation to move focus between controls checkbox.
This example sets the control's TabIndex.
Me.TabIndex = 2
DesktopTable.Tooltip
Tooltip As String
Text of help message displayed as a Windows or Linux "tooltip" or macOS help tag.
The tip/tag is displayed when the user hovers the mouse cursor over the control.
This example adds a tooltip to a control:
Me.Tooltip = "Click to bark."
DesktopTable.Top
Top As Integer
The distance from the top of the control to the top of its containing window or container.
This example sets the top of the control to 140 points from the top of the window:
Me.Top = 140
DesktopTable.TopInset
TopInset As Double
Free, non-clickable area before the first row, in points. Use it to keep the first row clear of something drawn over the upper edge.
This example sets the free, non-clickable area before the first row, in points:
Table1.TopInset = 1.0
DesktopTable.Transparent
Transparent As Boolean
Determines whether the control is transparent on Windows. The default is False. Has no effect on macOS or Linux.
Transparent controls draw more slowly and use more memory in order to cache the background. Unless you absolutely require transparency, leave this set to False.
For projects that were created prior to 2018r1, this property defaults to True to emulate previous behavior. Consider changing it to False to improve performance if you do not require transparency.
This example sets the property:
Table1.Transparent = True
DesktopTable.Underline
Underline As Boolean
Base font style. It applies to every cell and to the column headers, unless a cell overrides it with CellUnderlineAt.
This example sets the base font style:
Table1.Underline = True
DesktopTable.Visible
Visible As Boolean
Determines whether the control is visible when its owning window is opened. The default is True: the control is visible.
The following code makes the control invisible:
Me.Visible = False
DesktopTable.Width
Width As Integer
The width (in points) of the control.
The following example resizes the control:
Me.Width = 200
DesktopTable.Window
Window As DesktopWindow
The control's parent window.
This property is read-only.
This code gets the parent window's Title property.
MessageBox(Me.Window.Title)
Method descriptions
DesktopTable.AcceptFileDrop
AcceptFileDrop(FileType As String)
Permits documents of type FileType to be dropped on the control. FileType must be a file type that you defined in via the FileType class or the File Type Sets Editor.
This code in the Opening event makes it possible for the user to drop either a picture or a file that is a jpeg image. The File Type Sets editor was used to define the “image/jpeg” file type. It is one of the “Common File Types” that is available in the editor.
Me.AcceptPictureDrop Me.AcceptFileDrop("image/jpeg")To restrict file drops to specific file types on macOS, in addition to creating a File Type (as a project item or via code) to define the file extension, you must also use the DragEnter event:
For example, to restrict drops to folders only:
If Not obj.FolderItem.IsFolder Then Return TrueTo restrict drops to a files with a specific extension:
If Not obj.FolderItem.Extension <> ".my_extension" Then Return True
DesktopTable.AcceptPictureDrop
AcceptPictureDrop
Permits Picture objects to be dropped on the control. This applies to pictures dragged from another control or application, not to image files dragged from the file system. To accept image files, use AcceptFileDrop instead.
If a control should accept pictures in a drag and drop, then AcceptPictureDrop needs to be called prior to the drop. Typically, it is in the Opening event of the control itself. For example, the line:
Me.AcceptPictureDropin the Opening event of the control that will receive the dragged pictures is needed. When the picture is dropped, the DropObject event is called and this is where you will put your code to handle the drop.
Opening Event:
Me.AcceptPictureDropDropObject Event:
If obj.PictureAvailable Then Me.RowImageAt(0) = obj.Picture End If
DesktopTable.AcceptRawDataDrop
AcceptRawDataDrop(Type As String)
Permits data (of the Type specified) to be dropped on the control.
The following specfies a generic file type defined in the File Type Sets editor.
Me.AcceptRawDataDrop("????")
DesktopTable.AcceptTextDrop
AcceptTextDrop
Permits text to be dropped on the control.
This line in the Opening event of a control that can accept dragged text.
Me.AcceptTextDrop
DesktopTable.AddAllExpandableRows
AddAllExpandableRows(rows As RowSet)
Appends all database rows as expandable rows and expands the column count if needed. Like AddAllRows, except that every row gets a disclosure widget - see AllowExpandableRows, and RowExpanded, which fills in the children.
This example appends all database rows as expandable rows:
Table1.AddAllExpandableRows(rows)
AddAllExpandableRows(items() As String)
Appends an expandable row (column 0) for each array element.
This example appends an expandable row for each array element:
Var items() As String = Array("Anna", "Berlin") Table1.AddAllExpandableRows(items)
AddAllExpandableRows(items(,) As String)
Appends one expandable row per row of the array: items(row, column). Every one of them gets a disclosure widget; RowExpanded fills in its children. The column count grows when a row carries more values than the table has columns, the way the RowSet overload does.
This example appends two expandable rows of two columns each:
Var items(1, 1) As String items(0, 0) = "Anna" items(0, 1) = "Berlin" items(1, 0) = "Bodo" items(1, 1) = "Atlanta" Table1.AddAllExpandableRows(items)
AddAllExpandableRows(ParamArray item As String)
Appends an expandable row (column 0) for each passed value.
This example appends an expandable row for each passed value:
Table1.AddAllExpandableRows("Anna", "Berlin")
AddAllExpandableRows(count As Integer)
Appends count empty rows - no text in any column. Every one of them gets a disclosure widget; RowExpanded fills in its children.
This example appends ten empty rows:
Table1.AddAllExpandableRows(10)
DesktopTable.AddAllRows
AddAllRows(rows As RowSet)
Appends all database rows and expands the column count if needed.
This example appends all database rows and expands the column count if needed:
Table1.AddAllRows(rows)
AddAllRows(items() As String)
Appends a new row (column 0) for each array element.
This example appends a new row (column 0) for each array element:
Var items() As String = Array("Anna", "Berlin") Table1.AddAllRows(items)
AddAllRows(items(,) As String)
Appends one row per row of the array: items(row, column), as DesktopListBox does. The column count grows when a row carries more values than the table has columns, the way the RowSet overload does.
This example appends two rows of two columns each:
Var items(1, 1) As String items(0, 0) = "Anna" items(0, 1) = "Berlin" items(1, 0) = "Bodo" items(1, 1) = "Atlanta" Table1.AddAllRows(items)
AddAllRows(ParamArray item As String)
Appends a new row (column 0) for each passed value.
This example appends a new row (column 0) for each passed value:
Table1.AddAllRows("Anna", "Berlin")
AddAllRows(count As Integer)
Appends count empty rows - no text in any column. For a table whose cells are filled afterwards through CellTextAt, drawn in PaintCellText, or are containers.
This example appends ten empty rows:
Table1.AddAllRows(10)
DesktopTable.AddColumn
AddColumn(header As String = "")
Appends a column on the right. The new column is empty in every row and its width follows the current ColumnWidths.
This example appends a column on the right:
Table1.AddColumn
DesktopTable.AddColumnAt
AddColumnAt(index As Integer, header As String = "")
Inserts a column; an index
>= ColumnCountappends. The cells of every row move along with their column, so existing content stays with the column it belonged to. The sorting column and the heading index follow the shift as well.This example inserts a column; an index >= ColumnCount appends:
Table1.AddColumnAt(0)
DesktopTable.AddExpandableRow
AddExpandableRow(items() As String)
Appends an expandable row; the array fills consecutive columns. Within the RowExpanded event the row is inserted as a child of a row currently being expanded.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
This example appends an expandable row; the array fills consecutive columns:
Var items() As String = Array("Anna", "Berlin") Table1.AddExpandableRow(items)
AddExpandableRow(ParamArray item As String)
Appends an expandable row; one or more parameters fill consecutive columns. Within the RowExpanded event the row is inserted as a child of a row currently being expanded.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
This example appends an expandable row; one or more parameters fill consecutive columns:
Table1.AddExpandableRow("Anna", "Berlin")
DesktopTable.AddExpandableRowAt
AddExpandableRowAt(row As Integer, text As String, depth As Integer = 0)
Inserts an expandable row at a position and depth. The row shows a disclosure widget once AllowExpandableRows is on. Its children are usually added in the RowExpanded event, not in advance.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
This example inserts an expandable row at a position and depth:
Table1.AddExpandableRowAt(0, "Berlin")
DesktopTable.AddListSelectionNotificationReceiver
AddListSelectionNotificationReceiver(receiver As ListSelectionNotificationReceiver)
Registers a
ListSelectionNotificationReceiver. The receiver is told about every selection change, which is how a database-bound control follows the table without a selection event of its own.This example registers a receiver that follows the selection:
Table1.AddListSelectionNotificationReceiver(receiver)
DesktopTable.AddRow
AddRow(items() As String)
Appends a new row; the array fills consecutive columns.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
AddRow(ParamArray item As String)
Appends a new row; multiple parameters fill consecutive columns.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
This example adds a row in one go and another one cell by cell:
Table1.AddRow("Anna", "Berlin") ' A row added one cell at a time Table1.AddRow("") Table1.CellTextAt(Table1.LastAddedRowIndex, 0) = "Bob"
DesktopTable.AddRowAt
AddRowAt(row As Integer, text As String, depth As Integer = 0)
Inserts a row at a position and hierarchy depth. An index beyond the last row appends. depth places the row inside the hierarchy below its parent.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
This example inserts a row at a position and hierarchy depth:
Table1.AddRowAt(0, "Berlin")
DesktopTable.CellAlignmentAt
CellAlignmentAt(row As Integer, column As Integer) As DesktopTable.Alignments
Alignment of a cell.
This example reads the alignment of a cell:
Var value As DesktopTable.Alignments = Table1.CellAlignmentAt(0, 1)
CellAlignmentAt(row As Integer, column As Integer, Assigns value As DesktopTable.Alignments)
Sets the alignment of a cell (AllRows or AllColumns).
This example sets the alignment of a cell:
Table1.CellAlignmentAt(0, 1) = DesktopTable.Alignments.Right
DesktopTable.CellAlignmentOffsetAt
CellAlignmentOffsetAt(row As Integer, column As Integer) As Integer
Distance of the alignment point from the right cell edge in points.
This example reads the distance of the alignment point from the right cell edge in points:
Var value As Integer = Table1.CellAlignmentOffsetAt(0, 1)
CellAlignmentOffsetAt(row As Integer, column As Integer, Assigns value As Integer)
Sets the alignment offset of a cell (AllRows or AllColumns). It applies to that cell only: the offset of its column, and with it the other cells and the heading, stays as it is, the same as in a list box. In a checkbox cell (CellTypes.CheckBox) the checkbox moves along with the text, by the same distance.
This example moves the text of a single cell 50 points to the right:
Table1.CellAlignmentOffsetAt(0, 1) = 50
DesktopTable.CellBoldAt
CellBoldAt(row As Integer, column As Integer) As Boolean
Bold style of a cell.
This example reads the bold style of a cell:
Var value As Boolean = Table1.CellBoldAt(0, 1)
CellBoldAt(row As Integer, column As Integer, Assigns value As Boolean)
Sets the bold style of a cell (AllRows or AllColumns).
This example sets the bold style of a cell:
Table1.CellBoldAt(0, 1) = True
DesktopTable.CellBorderColorAt
CellBorderColorAt(row As Integer, column As Integer) As ColorGroup
Border color of a cell.
This example reads the border color of a cell:
Var value As ColorGroup = Table1.CellBorderColorAt(0, 1)
CellBorderColorAt(row As Integer, column As Integer, Assigns value As ColorGroup)
Sets the border color of a cell (AllRows or AllColumns).
This example sets the border color of a cell:
Table1.CellBorderColorAt(0, 1) = New ColorGroup(&cD93025, &cC5372C)
DesktopTable.CellBoundsAt
CellBoundsAt(row As Integer, column As Integer) As Rect
The cell's rectangle in the table's own coordinates - scroll, frozen bands and RTL applied; merge anchors report the merged rectangle.
This example places a control of your own over a cell:
' Place your own control over a cell Var r As Rect = Table1.CellBoundsAt(2, 1) ProgressBar1.Left = Table1.Left + r.Left ProgressBar1.Top = Table1.Top + r.Top ProgressBar1.Width = r.Width
DesktopTable.CellCheckBoxEnabledAt
CellCheckBoxEnabledAt(row As Integer, column As Integer) As Boolean
Whether a checkbox cell is clickable (default: True).
This example reads whether a checkbox cell is clickable:
Var value As Boolean = Table1.CellCheckBoxEnabledAt(0, 1)
CellCheckBoxEnabledAt(row As Integer, column As Integer, Assigns value As Boolean)
Enables/disables a checkbox cell (AllRows or AllColumns).
This example sets the enables/disables a checkbox cell:
Table1.CellCheckBoxEnabledAt(0, 1) = True
DesktopTable.CellCheckBoxStateAt
CellCheckBoxStateAt(row As Integer, column As Integer) As DesktopCheckBox.VisualStates
State (Checked/Unchecked/Indeterminate) of a checkbox cell.
This example reads the state (Checked/Unchecked/Indeterminate) of a checkbox cell:
Var value As DesktopCheckBox.VisualStates = Table1.CellCheckBoxStateAt(0, 1)
CellCheckBoxStateAt(row As Integer, column As Integer, Assigns value As DesktopCheckBox.VisualStates)
Sets the state of a checkbox cell (AllRows or AllColumns).
This example sets the state of a checkbox cell:
Table1.CellCheckBoxStateAt(0, 1) = DesktopCheckBox.VisualStates.Checked
DesktopTable.CellCheckBoxValueAt
CellCheckBoxValueAt(row As Integer, column As Integer) As Boolean
Value of a checkbox cell.
This example reads the value of a checkbox cell:
Var value As Boolean = Table1.CellCheckBoxValueAt(0, 1)
CellCheckBoxValueAt(row As Integer, column As Integer, Assigns value As Boolean)
Sets the value of a checkbox cell.
This example sets the value of a checkbox cell:
Table1.CellCheckBoxValueAt(0, 1) = True
DesktopTable.CellIsMerged
CellIsMerged(row As Integer, column As Integer) As Boolean
Whether a cell belongs to a merge (anchor or covered). It is True for the anchor as well as for every cell the merge covers. CellMergeBounds reports the extent.
This example reads whether a cell belongs to a merge:
Var value As Boolean = Table1.CellIsMerged(0, 1)
DesktopTable.CellItalicAt
CellItalicAt(row As Integer, column As Integer) As Boolean
Italic style of a cell.
This example reads the italic style of a cell:
Var value As Boolean = Table1.CellItalicAt(0, 1)
CellItalicAt(row As Integer, column As Integer, Assigns value As Boolean)
Sets the italic style of a cell (AllRows or AllColumns).
This example sets the italic style of a cell:
Table1.CellItalicAt(0, 1) = True
DesktopTable.CellMergeBounds
CellMergeBounds(row As Integer, column As Integer, ByRef anchorRow As Integer, ByRef anchorColumn As Integer, ByRef rowSpan As Integer, ByRef columnSpan As Integer) As Boolean
Anchor and span of the merge covering the cell; False if unmerged, in which case the
ByRefvalues are left untouched.This example reads the anchor and span of the merge covering the cell; False if unmerged, in which case the ByRef values are left untouched:
Var value As Boolean = Table1.CellMergeBounds(0, 1, anchorRow, anchorColumn, rowSpan, columnSpan)
DesktopTable.CellProgressBarMaximumValueAt
CellProgressBarMaximumValueAt(row As Integer, column As Integer) As Double
Upper bound of a progress bar cell (default: 100).
This example reads the upper bound of a progress bar cell:
Var value As Double = Table1.CellProgressBarMaximumValueAt(0, 1)
CellProgressBarMaximumValueAt(row As Integer, column As Integer, Assigns value As Double)
Sets the upper bound of a progress bar cell (AllRows or AllColumns). Unlike DesktopProgressBar a value <= 0 does NOT switch to an indeterminate bar (a cell has no animation) - the bar simply stays empty.
This example sets the upper bound of a progress bar cell:
Table1.CellProgressBarMaximumValueAt(0, 1) = 1.0
DesktopTable.CellProgressBarValueAt
CellProgressBarValueAt(row As Integer, column As Integer) As Double
Current value of a progress bar cell.
This example reads the current value of a progress bar cell:
Var value As Double = Table1.CellProgressBarValueAt(0, 1)
CellProgressBarValueAt(row As Integer, column As Integer, Assigns value As Double)
Sets the value of a progress bar cell (AllRows or AllColumns). The value is stored unchanged; only the drawing clamps it to 0 .. MaximumValue.
This example sets the value of a progress bar cell:
Table1.CellProgressBarValueAt(0, 1) = 1.0
DesktopTable.CellTagAt
CellTagAt(row As Integer, column As Integer) As Variant
Invisible companion value of a cell.
This example reads the invisible companion value of a cell:
Var value As Variant = Table1.CellTagAt(0, 1)
CellTagAt(row As Integer, column As Integer, Assigns value As Variant)
Sets the companion value of a cell (AllRows or AllColumns).
This example sets the companion value of a cell:
Table1.CellTagAt(0, 1) = "myTag"
DesktopTable.CellTextAt
CellTextAt(row As Integer, column As Integer = 0) As String
Text of a cell. row = AllRows returns the whole column (EndOfLine-separated), column = AllColumns the whole row (tab-separated).
CellTextAt(row As Integer, column As Integer = 0, Assigns value As String)
Sets the text of a cell. row = AllRows distributes an EndOfLine-separated value across the column, column = AllColumns a tab-separated value across the row.
This example reads and writes a cell, and reads a whole row:
Var name As String = Table1.CellTextAt(3, 0) Table1.CellTextAt(3, 1) = "Hamburg" ' row = -1 returns a whole column, column = -1 a whole row (Tab-separated) Var wholeRow As String = Table1.CellTextAt(3, -1)
DesktopTable.CellTooltipAt
CellTooltipAt(row As Integer, column As Integer) As String
Tooltip of a cell.
This example reads the tooltip of a cell:
Var value As String = Table1.CellTooltipAt(0, 1)
CellTooltipAt(row As Integer, column As Integer, Assigns value As String)
Sets the tooltip of a cell (AllRows or AllColumns).
This example sets the tooltip of a cell:
Table1.CellTooltipAt(0, 1) = "Berlin"
DesktopTable.CellTypeAt
CellTypeAt(row As Integer, column As Integer) As DesktopTable.CellTypes
Type of a cell; Default means: the column type applies.
This example reads the type of a cell; Default means: the column type applies:
Var value As DesktopTable.CellTypes = Table1.CellTypeAt(0, 1)
CellTypeAt(row As Integer, column As Integer, Assigns value As DesktopTable.CellTypes)
Sets the type of a cell, overriding the column type (AllRows or AllColumns).
This example sets the type of a cell, overriding the column type:
Table1.CellTypeAt(0, 1) = DesktopTable.CellTypes.CheckBox
DesktopTable.CellUnderlineAt
CellUnderlineAt(row As Integer, column As Integer) As Boolean
Underline style of a cell.
This example reads the underline style of a cell:
Var value As Boolean = Table1.CellUnderlineAt(0, 1)
CellUnderlineAt(row As Integer, column As Integer, Assigns value As Boolean)
Sets the underline style of a cell (AllRows or AllColumns).
This example sets the underline style of a cell:
Table1.CellUnderlineAt(0, 1) = True
DesktopTable.Close
Close
Closes a control.
Closing a control permanently removes the control from memory, making it impossible to access. You can close both non-indexed controls and indexed controls. When you close an indexed control, the indexes for the remaining controls will shift downward so that the indexes start with zero and are consecutive.
The following code closes the control. When this is executed from a visible control, the control disappears from the window.
Me.Close
DesktopTable.CollapseAllRows
CollapseAllRows
Collapses every expanded row, top to bottom. Collapsing a row removes its whole subtree in one step (see CollapseRowInternal), so descendants are never visited individually - a single forward pass over the shrinking row list is enough, and DataRowCount is re-read every iteration to reflect that shrink.
This example collapses every expanded row, top to bottom:
Table1.CollapseAllRows
DesktopTable.ColumnAlignmentAt
ColumnAlignmentAt(column As Integer) As DesktopTable.Alignments
Alignment of a column.
This example reads the alignment of a column:
Var value As DesktopTable.Alignments = Table1.ColumnAlignmentAt(1)
ColumnAlignmentAt(column As Integer, Assigns value As DesktopTable.Alignments)
Sets the alignment of a column (AllColumns).
This example sets the alignment of a column:
Table1.ColumnAlignmentAt(1) = DesktopTable.Alignments.Right
DesktopTable.ColumnAlignmentOffsetAt
ColumnAlignmentOffsetAt(column As Integer) As Integer
Alignment offset of a column in points.
This example reads the alignment offset of a column in points:
Var value As Integer = Table1.ColumnAlignmentOffsetAt(1)
ColumnAlignmentOffsetAt(column As Integer, Assigns value As Integer)
Sets the alignment offset of a column (AllColumns). In checkbox cells (CellTypes.CheckBox) the checkbox moves along with the text, by the same distance.
This example sets the alignment offset of a column:
Table1.ColumnAlignmentOffsetAt(1) = 0
DesktopTable.ColumnAttributesAt
ColumnAttributesAt(column As Integer) As DesktopTableColumn
Returns the column attribute object; AllColumns affects all columns.
This example returns the column attribute object; AllColumns affects all columns:
Var value As DesktopTableColumn = Table1.ColumnAttributesAt(1)
ColumnAttributesAt(column As Integer, Assigns value As DesktopTableColumn)
Applies the attributes of the passed object to the *column*(s).
This example sets the applies the attributes of the passed object to the column:
Table1.ColumnAttributesAt(1) = myColumn
DesktopTable.ColumnFromXY
ColumnFromXY(x As Integer, y As Integer) As Integer
Column index at a control-space point,
-1outside. The point is in the table's own coordinates, as the mouse events deliver them. A hidden column is never returned, and a point over the header or outside the table gives -1.This example reads the column index at a control-space point, -1 outside:
Var value As Integer = Table1.ColumnFromXY(10, 20)
DesktopTable.ColumnHeaderAt
ColumnHeaderAt(index As Integer) As String
Heading of a column.
This example reads the heading of a column:
Var value As String = Table1.ColumnHeaderAt(0)
ColumnHeaderAt(index As Integer, Assigns value As String)
Sets the column heading. index = AllColumns distributes a tab-separated value across all columns. "" resets to the default.
This example sets the column heading:
Table1.ColumnHeaderAt(0) = "Berlin"
DesktopTable.Columns
Columns As Iterable
Allows For Each column As DesktopTableColumn In table.Columns. The objects handed out are DesktopTableColumn accessors, so a loop can change widths and visibility directly.
This example allows For Each column As DesktopTableColumn In table.Columns:
For Each c As DesktopTableColumn In Table1.Columns c.UserResizable = False Next
DesktopTable.ColumnSortDirectionAt
ColumnSortDirectionAt(column As Integer) As DesktopTable.SortDirections
Sort direction of a column.
This example reads the sort direction of a column:
Var value As DesktopTable.SortDirections = Table1.ColumnSortDirectionAt(1)
ColumnSortDirectionAt(column As Integer, Assigns value As DesktopTable.SortDirections)
Sets the sort direction of a column; None disables sorting via the header.
This example sets the sort direction of a column; None disables sorting via the header:
Table1.ColumnSortDirectionAt(1) = DesktopTable.SortDirections.Ascending
DesktopTable.ColumnSortTypeAt
ColumnSortTypeAt(column As Integer) As DesktopTable.SortTypes
Sortability of a column.
This example reads the sortability of a column:
Var value As DesktopTable.SortTypes = Table1.ColumnSortTypeAt(1)
ColumnSortTypeAt(column As Integer, Assigns value As DesktopTable.SortTypes)
Sets the sortability of a column (AllColumns).
This example sets the sortability of a column:
Table1.ColumnSortTypeAt(1) = DesktopTable.SortTypes.Sortable
DesktopTable.ColumnTagAt
ColumnTagAt(column As Integer) As Variant
Companion value of a column.
This example reads the companion value of a column:
Var value As Variant = Table1.ColumnTagAt(1)
ColumnTagAt(column As Integer, Assigns value As Variant)
Sets the companion value of a column (AllColumns).
This example sets the companion value of a column:
Table1.ColumnTagAt(1) = "myTag"
DesktopTable.ColumnTypeAt
ColumnTypeAt(column As Integer) As DesktopTable.CellTypes
Type of a column.
This example reads the type of a column:
Var value As DesktopTable.CellTypes = Table1.ColumnTypeAt(1)
ColumnTypeAt(column As Integer, Assigns value As DesktopTable.CellTypes)
Sets the type of a column; individual cells can override it via CellTypeAt.
This example sets the type of a column; individual cells can override it via CellTypeAt:
Table1.ColumnTypeAt(1) = DesktopTable.CellTypes.CheckBox
DesktopTable.ColumnVisibleAt
ColumnVisibleAt(index As Integer) As Boolean
True if the column is shown.
ColumnVisibleAt(index As Integer, Assigns value As Boolean)
Shows or hides the column (AllColumns). A hidden column keeps its data, width expressions and index - it only takes no space: the layout gives it width 0, it raises no paint events, and it cannot be hit, resized, dragged or edited.
This example hides a single column and shows every column again:
' Hide the second column without removing it Table1.ColumnVisibleAt(1) = False ' Show every column again Table1.ColumnVisibleAt(DesktopTable.AllColumns) = True
DesktopTable.ContainerForCellAt
ContainerForCellAt(row As Integer, column As Integer) As DesktopContainer
The container currently shown in a cell, or Nil. It exists only while the cell is on screen: the table asks ContainerAt when a cell appears and lets the instance go again when the cell leaves.
This example reads the container of a cell:
Var container As DesktopContainer = Table1.ContainerForCellAt(0, 2)
DesktopTable.DrawInto
DrawInto(g As Graphics, left As Integer, top As Integer)
Renders the table into another
Graphicscontext. It draws the table as it currently looks, which is how it ends up in a printout or in a picture.This example renders the table into another Graphics context:
Table1.DrawInto(g, 10, 10)
DesktopTable.EditCellAt
EditCellAt(row As Integer, column As Integer)
Scrolls the cell into view and starts inline editing. The cell must be of type TextField or TextArea, set through CellTypeAt or ColumnTypeAt. A cell in a hidden column cannot be edited, and an editor that is already open is committed first.
This example scrolls the cell into view and starts inline editing:
Table1.EditCellAt(0, 1)
DesktopTable.ExpandAllRows
ExpandAllRows
Expands every expandable row, including rows only revealed by expanding an earlier one. It works down the hierarchy, so children that only appear once their parent is open are expanded as well.
This example expands every expandable row, including rows only revealed by expanding an earlier one:
Table1.ExpandAllRows
DesktopTable.MergeCells
MergeCells(row As Integer, column As Integer, rowSpan As Integer, columnSpan As Integer)
Merges a rectangular range;
(row, column)is the anchor. Raises InvalidArgumentException on overlap. The anchor keeps the content and the styling; the cells it covers keep their data but are no longer drawn. A merge overlapping an existing one is refused.This example merges a rectangular range; (row, column) is the anchor:
Table1.MergeCells(0, 1, 2, 3)
DesktopTable.Open
Open(file As FolderItem, delimiter As String = ",", importHeaders As Boolean = True)
Reads a delimited text file in UTF-8 and replaces the entire content, so save anything you still need first. The delimiter has to match the file: a comma for CSV,
Chr(9)for TSV. Quoted fields are unquoted following RFC 4180, the column count grows to the widest record, and in DataSource mode the call raises an UnsupportedOperationException.This example reads a delimited text file in UTF-8 and replaces the entire content, so save anything you still need first:
Table1.Open(f)
DesktopTable.PressColumnHeaderAt
PressColumnHeaderAt(column As Integer)
Triggers a header click programmatically. It behaves as though the user had clicked the header: ColumnHeaderPressed fires and a sortable column is sorted.
This example triggers a header click programmatically:
Table1.PressColumnHeaderAt(1)
DesktopTable.Refresh
Refresh(immediately As Boolean = False)
Redraws the portion specified of the contents of the control the next time the OS redraws the control or immediately if True is passed.
If you are calling this so frequently that you experience a slowdown in your code, pass True for the immediately parameter.
Calling this method causes the Render event to fire.
Refresh the entire area immediately:
Me.Refresh(True)
DesktopTable.Refresh
Refresh(x As Integer, y As Integer, width As Integer, height As Integer, immediately As Boolean = False)
Redraws the portion specified of the contents of the control the next time the OS redraws the control or immediately if True is passed.
Refresh a portion of the area the next time the OS redraws the control:
Me.Refresh(100, 150, 200, 300)
DesktopTable.RefreshCellAt
RefreshCellAt(row As Integer, column As Integer)
Redraws one cell;
-1for row or column redraws the whole column or row. Use it instead of a full refresh when a single value changed. If the cell is part of a merge, the whole merge is redrawn.This example redraws one cell; -1 for row or column redraws the whole column or row:
Table1.RefreshCellAt(0, 1)
DesktopTable.ReloadFromDataSource
ReloadFromDataSource
Re-reads row count, row heights and cell content from the data source. Selection and scroll position are kept, so it is the call to make after the data behind a TableDataSource changed.
This example re-reads row count, row heights and cell content from the data source:
Table1.ReloadFromDataSource
DesktopTable.RemoveAllColumns
RemoveAllColumns
Removes all columns (ColumnCount = 0, empty table). The cell content goes with the columns. The rows themselves remain, but without columns nothing is drawn.
This example removes all columns:
Table1.RemoveAllColumns
DesktopTable.RemoveAllMerges
RemoveAllMerges
Removes all cell merges. The cells keep the data they had before the merge.
This example removes all cell merges:
Table1.RemoveAllMerges
DesktopTable.RemoveAllRows
RemoveAllRows
Removes all rows. With an editable data source the source is cleared, otherwise (in-memory only) the local storage.
This example removes all rows:
Table1.RemoveAllRows
DesktopTable.RemoveColumnAt
RemoveColumnAt(index As Integer)
Removes a column; columns to its right move left. The cells of that column are removed from every row, and merges, the sorting column and the heading index follow the shift.
This example removes a column; columns to its right move left:
Table1.RemoveColumnAt(0)
DesktopTable.RemoveListSelectionNotificationReceiver
RemoveListSelectionNotificationReceiver(receiver As ListSelectionNotificationReceiver)
Unregisters a receiver. Removing a receiver that was never registered does nothing.
This example unregisters the receiver again:
Table1.RemoveListSelectionNotificationReceiver(receiver)
DesktopTable.RemoveRowAt
RemoveRowAt(index As Integer)
Removes the row. With an editable data source it is removed (incl. subtree) from the source, otherwise from the in-memory storage.
If you want to improve performance when adding and removing rows, you can set AllowRowAnimation to False.
This example removes the row:
Table1.RemoveRowAt(0)
DesktopTable.ReusableContainer
ReusableContainer(identifier As String) As DesktopContainer
Called from inside ContainerAt: hands back a container an earlier cell has finished with, or Nil when there is none. The identifier is yours to choose, and a table whose cells hold containers of different kinds keeps them apart by it.
With the reuse the table gets by with about as many instances as there are visible cells, however many rows it has. Without it every cell scrolling into view builds one of its own. How many are kept is ContainerCacheSize.
This example asks for a used instance and builds one only when there is none:
Var container As DesktopContainer = Me.ReusableContainer("CurrencyContainer") If container = Nil Then container = New CurrencyContainer End If
DesktopTable.RowAt
RowAt(row As Integer) As DesktopTableRow
Lightweight read-only accessor for one row. The object reads what the table currently holds for that row index, so it is a view of the row rather than a copy. Changing a value goes through the table, for example CellTextAt.
This example reads the lightweight read-only accessor for one row:
Var value As DesktopTableRow = Table1.RowAt(0)
DesktopTable.RowDepthAt
RowDepthAt(row As Integer) As Integer
Hierarchy depth of a row (0 = top level). The depth is what the table indents by and what a disclosure widget opens into.
This example reads the hierarchy depth of a row:
Var value As Integer = Table1.RowDepthAt(0)
DesktopTable.RowExpandableAt
RowExpandableAt(row As Integer) As Boolean
True if the row shows a disclosure widget. Only a row marked as expandable can be opened by the user, and only while AllowExpandableRows is on.
This example reads the true if the row shows a disclosure widget:
Var value As Boolean = Table1.RowExpandableAt(0)
RowExpandableAt(row As Integer, Assigns value As Boolean)
Shows or hides the row's disclosure widget.
This example shows or hides the row's disclosure widget:
Table1.RowExpandableAt(0) = True
DesktopTable.RowExpandedAt
RowExpandedAt(row As Integer) As Boolean
Disclosure state of a row.
This example reads the disclosure state of a row:
Var value As Boolean = Table1.RowExpandedAt(0)
RowExpandedAt(row As Integer, Assigns value As Boolean)
Expands or collapses the row and fires RowExpanded or RowCollapsed.
This example expands or collapses the row and fires RowExpanded or RowCollapsed:
Table1.RowExpandedAt(0) = True
DesktopTable.RowForContainer
RowForContainer(container As DesktopContainer) As Integer
The row a container is currently shown in, or -1.
A reused container cannot remember its own row: row numbers move with every insertion, removal and sort, and the same instance serves other rows later. So a control inside the container asks at the moment it is used.
This example writes the value of a control back into the row its container serves:
Var row As Integer = Table1.RowForContainer(sender) If row < 0 Then Return Table1.CellTagAt(row, 2) = value
DesktopTable.RowFromXY
RowFromXY(x As Integer, y As Integer) As Integer
Row index at a control-space point,
-1outside. The point is in the table's own coordinates, as the mouse events deliver them. A point over the header or below the last row gives -1.This example reads the row index at a control-space point, -1 outside:
Var value As Integer = Table1.RowFromXY(10, 20)
DesktopTable.RowHeightAt
RowHeightAt(row As Integer) As Double
Height of a row in points (default height as long as no custom one is set).
This example reads the height of a row in points:
Var value As Double = Table1.RowHeightAt(0)
RowHeightAt(row As Integer, Assigns height As Double)
Sets an individual row height; values <= 0 restore the default height.
This example sets an individual row height; values <= 0 restore the default height:
Table1.RowHeightAt(0) = 24
DesktopTable.RowImageAt
RowImageAt(index As Integer) As Picture
Image of a row.
This example reads the image of a row:
Var value As Picture = Table1.RowImageAt(0)
RowImageAt(index As Integer, Assigns value As Picture)
Sets the row's image; it is drawn to the left of the text.
This example sets the row's image; it is drawn to the left of the text:
Table1.RowImageAt(0) = myPicture
DesktopTable.Rows
Rows As Iterable
Allows For Each row As DesktopTableRow In lb.Rows. The objects handed out are DesktopTableRow accessors, so the loop reads the live content rather than a copy.
This example allows For Each row As DesktopTableRow In lb.Rows:
' Collect the names of the selected rows Var names() As String For Each r As DesktopTableRow In Table1.Rows If r.Selected Then names.Add(r.CellTextAt(0)) Next
DesktopTable.RowSelectedAt
RowSelectedAt(index As Integer) As Boolean
Selection state of a row.
This example reads the selection state of a row:
Var value As Boolean = Table1.RowSelectedAt(0)
RowSelectedAt(index As Integer, Assigns value As Boolean)
Sets the row's selection state (multiple rows only with RowSelectionType Multiple).
This example sets the row's selection state:
Table1.RowSelectedAt(0) = True
DesktopTable.RowTagAt
RowTagAt(row As Integer) As Variant
Companion value of a row.
This example reads the companion value of a row:
Var value As Variant = Table1.RowTagAt(0)
RowTagAt(row As Integer, Assigns value As Variant)
Sets the row's companion value.
This example sets the row's companion value:
Table1.RowTagAt(0) = "myTag"
DesktopTable.Save
Save(file As FolderItem, delimiter As String = ",", exportHeaders As Boolean = True)
Writes the entire content as a delimited text file in UTF-8. The delimiter decides the format: a comma - the default - writes CSV,
Chr(9)writes TSV. Cells containing the delimiter, a double quote or a line break are quoted following RFC 4180, so the file reads back unchanged with Open. It works in DataSource mode as well, where the rows come from the source.This example asks for a file and writes the table into it:
Var f As FolderItem = FolderItem.ShowSaveFileDialog("text/csv", "Table.csv") If f <> Nil Then Table1.Save(f)
DesktopTable.ScrollTo
ScrollTo(row As Integer, column As Integer = 0)
Scrolls so the row becomes the top-most and the column the left-most visible. It scrolls no further than the content allows, so the last rows may stay where they are.
This example scrolls so the row becomes the top-most and the column the left-most visible:
Table1.ScrollTo(0)
DesktopTable.SectionHeaderAt
SectionHeaderAt(row As Integer) As Boolean
Whether the row is a section header. While scrolling, the current section's header stays pinned at the top (below the column header) until the next section header scrolls up and pushes it out; the normal rows scroll behind it.
This example reads whether the row is a section header:
Var value As Boolean = Table1.SectionHeaderAt(0)
SectionHeaderAt(row As Integer, Assigns value As Boolean)
Marks (or unmarks) the row as a section header (sticky while scrolling).
This example marks (or unmarks) the row as a section header:
Table1.SectionHeaderAt(0) = True
DesktopTable.SelectAll
SelectAll
Selects every row and fires SelectionChanged; meaningful with
RowSelectionType = Multiple. It only has an effect with RowSelectionType set to Multiple. The table also handles the Edit menu itemEditSelectAllitself while it has the focus.This example allows multiple selection and selects every row:
Table1.RowSelectionType = DesktopTable.RowSelectionTypes.Multiple Table1.SelectAll
DesktopTable.SetFocus
SetFocus
If applicable, sets the focus to the DesktopUIControl. KeyDown events are directed to the control.
If the control cannot get the focus on the platform on which the application is running, SetFocus does nothing. The SetFocus method of the DesktopWindow class or the ClearFocus method can be used to remove the focus from the control that currently has the focus, leaving no control with the focus.
Note
On macOS, you need Full Keyboard Access turned on in System Preferences (Keyboard->Shortcuts) in order to manually set focus to non-text controls.
The following example in the Opening event sets the focus to the that control. If another control has the focus when this line is executed, then the user sees this control gets the focus.
Me.SetFocus
DesktopTable.Sort
Sort
Sorts by SortingColumn and its sort direction. The rows are compared as text unless the RowComparison event decides the order. With a SortableTableDataSource the source sorts instead.
This example sorts by SortingColumn and its sort direction:
Table1.Sort
DesktopTable.UnmergeCellsAt
UnmergeCellsAt(row As Integer, column As Integer)
Removes the merge covering the cell (anchor or covered). The cells the merge covered are drawn on their own again, with the data they still carry.
This example removes the merge covering the cell:
Table1.UnmergeCellsAt(0, 1)
Event descriptions
DesktopTable.Activated
Activated
The control is activated. In a single window interface, the Activate event fires when the parent window is activated. See the DesktopApplication and DesktopWindow Activate events.
This can be because the app is launched or a window belonging to another app is no longer frontmost (active). The Deactivate event fires when another window becomes active. In a single window interface, the Activate event fires when the window is activated, e.g., when the app first displays the window.
This example reloads the data when the window comes forward again:
' The window came forward again - show the live data Me.ReloadFromDataSource
DesktopTable.ApplyLeadingActionsForRow
ApplyLeadingActionsForRow(row As Integer) As DesktopTableRowAction()
macOS, Windows and Linux (touchpad). Actions for a two-finger swipe from the leading edge. Raised once, when the gesture is recognised. An empty array leaves the gesture as an ordinary scroll.
This example offers a single blue action on the leading edge:
Var actions() As DesktopTableRowAction Var unread As New DesktopTableRowAction("Unread", "unread") unread.BackgroundColor = New ColorGroup(&c2F6FDB, &c25589F) actions.Add(unread) Return actions
DesktopTable.ApplyTrailingActionsForRow
ApplyTrailingActionsForRow(row As Integer) As DesktopTableRowAction()
macOS, Windows and Linux (touchpad). Actions for a swipe from the trailing edge, same contract as above.
This example offers a red delete action, except on rows marked as locked:
' No actions for the rows that may not be deleted If Me.RowTagAt(row) = "locked" Then Return Nil Var actions() As DesktopTableRowAction Var remove As New DesktopTableRowAction("Delete", "delete") remove.BackgroundColor = New ColorGroup(&cD93025, &cC5372C) actions.Add(remove) Return actions
DesktopTable.CellAction
CellAction(row As Integer, column As Integer)
An inline editor was committed. It fires when the user leaves an editable cell, by pressing Return or Tab or by clicking elsewhere, and also when a checkbox cell is clicked. The content need not have changed.
This example writes the edited value back into the record behind the row:
' The user finished editing: write the value back mRecords(row).Name = Me.CellTextAt(row, column) mRecords(row).Modified = True
DesktopTable.CellFocusLost
CellFocusLost(row As Integer, column As Integer)
The inline editor lost focus. The user moved on to another cell or ended the editing with Return, Tab or Escape.
This example formats the value again once editing ends:
' Editing ended - show the value formatted again Me.CellTextAt(row, column) = Val(Me.CellTextAt(row, column)).ToString("#,##0.00")
DesktopTable.CellFocusReceived
CellFocusReceived(row As Integer, column As Integer)
The inline editor gained focus. The cell is now being edited, so this is the place to preselect text or adjust the editor.
This example preselects the text so typing replaces it:
' Preselect the text so typing replaces it If Me.ActiveTextControl <> Nil Then Me.ActiveTextControl.SelectAll
DesktopTable.CellKeyDown
CellKeyDown(row As Integer, column As Integer, key As String) As Boolean
The user pressed key while the inline editor of a cell (row, column) has the focus. Return True to swallow the key, for example to refuse characters the column does not accept.
This example refuses anything but digits in the amount column:
' Only digits in the amount column If column = 2 And key.Asc > 31 And InStr("0123456789.", key) = 0 Then Return True
DesktopTable.CellPressed
CellPressed(row As Integer, column As Integer, x As Integer, y As Integer) As Boolean
Cell was clicked; x, y are cell-relative. It fires before the table changes the selection. Return True to keep the click to yourself, which is how a clickable area inside a cell is built.
This example treats a click on the icon column as opening the record:
' A click in the icon column opens the record instead of selecting the row If column = 0 And x < 20 Then ShowRecord(row) Return True End If
DesktopTable.CellTextChanged
CellTextChanged(row As Integer, column As Integer)
The editor's text changed. It fires on every keystroke in the inline editor, not only when the editing ends.
This example enables the Save button as soon as something is typed:
' Enable the Save button as soon as something is typed SaveButton.Enabled = True
DesktopTable.Closing
Closing
The control is going away. The control is being destroyed. An open inline editor has already been committed at this point.
This example stores the column widths for the next launch:
' Keep the column widths for the next launch mPreferences.ColumnWidths = Me.ColumnWidths
DesktopTable.ColumnHeaderPressed
ColumnHeaderPressed(column As Integer) As Boolean
DesktopTable.ColumnReordered
ColumnReordered(fromColumn As Integer, toColumn As Integer)
A column drag finished. The columns are already in their new order, so the indices reported are the new ones.
This example remembers the order the user arranged:
' Remember the new order by the headings Var headings() As String For i As Integer = 0 To Me.LastColumnIndex headings.Add(Me.ColumnHeaderAt(i)) Next mPreferences.ColumnOrder = String.FromArray(headings, Chr(9))
DesktopTable.ColumnReordering
ColumnReordering(fromColumn As Integer, toColumn As Integer) As Boolean
A column drag is in progress; return True to reject. It fires while the column is being dragged. Return True to refuse that particular move; the column then stays where it is.
This example refuses to move the status column:
' The status column has to stay where it is If fromColumn = 0 Or toColumn = 0 Then Return True
DesktopTable.ColumnResized
ColumnResized(column As Integer, width As Integer)
A column-width drag finished; width is the final width in whole points. Fires only when the width actually changed, so a plain click on the divider stays silent.
This example stores the width the user settled on:
' Store the width the user settled on mPreferences.ColumnWidth(column) = width
DesktopTable.ColumnResizing
ColumnResizing(column As Integer, width As Integer)
Fires on every step of a column-width drag, reporting the whole-point width about to be applied. Purely informational - see the note below.
This example shows the width in a status label while it is dragged:
' Show the width while it is being dragged StatusLabel.Text = width.ToString + " pt"
DesktopTable.ColumnSorted
ColumnSorted(column As Integer) As Boolean
Fires before sorting; return True to sort yourself. It fires before the rows are rearranged. Return True to sort the data yourself, for example in the database the rows come from.
This example lets the database sort and reloads afterwards:
' Let the database sort, then reload mRowSet = mDatabase.SelectSQL("SELECT * FROM People ORDER BY " + FieldName(column)) Me.ReloadFromDataSource Return True
DesktopTable.ConstructContextualMenu
ConstructContextualMenu(base As DesktopMenuItem, x As Integer, y As Integer) As Boolean
Build the contextual menu. A right-click first selects the row under the pointer, then this event fires so you can add items. Return True to suppress the menu.
This example adds an entry for the row under the pointer:
Var row As Integer = Me.RowFromXY(x, y) If row < 0 Then Return False base.AddMenu(New DesktopMenuItem("Delete " + Me.CellTextAt(row, 0), row)) Return True
DesktopTable.ContainerAt
ContainerAt(row As Integer, column As Integer) As DesktopContainer
Supplies the container for a cell of type Container. It fires when such a cell comes into view, and what it returns is shown in that cell until the cell leaves again. Nil leaves the cell empty.
Ask ReusableContainer first and build a new instance only when it returns Nil, then fill it with the row's data. The same instance serves other rows later, so everything that belongs to the row is set here.
A column's number is a position, not a name: AllowColumnReordering lets the user move the column, and the event then arrives with its new number. A handler that compares the number against a fixed one returns Nil for every cell from that moment on, and the column stays empty. Where the handler has to tell one container column from another, ColumnTagAt is the identifier that moves with the column.
This example hands out a container with a popup menu in it:
If Me.ColumnTagAt(column) <> "currency" Then Return Nil Var container As DesktopContainer = Me.ReusableContainer("CurrencyContainer") If container = Nil Then container = New CurrencyContainer AddHandler CurrencyContainer(container).CurrencySelected, WeakAddressOf CurrencySelected End If Var value As Variant = Me.CellTagAt(row, column) CurrencyContainer(container).Init(If(value.IsNull, 0, value.IntegerValue)) Return container
DesktopTable.ContainerRemovedAt
ContainerRemovedAt(row As Integer, column As Integer, container As DesktopContainer) As Boolean
A cell has given up its container: it scrolled out of view, its row is gone or its type changed. Return True to keep the instance yourself - the table then only lets go of it - and False to have the table dispose of it.
A container fetched through ReusableContainer goes into the table's own pool instead, so for those this event fires only once the pool is full - see ContainerCacheSize.
This example leaves the instance to the table:
Return False
DesktopTable.ContextualMenuItemSelected
ContextualMenuItemSelected(selectedItem As DesktopMenuItem) As Boolean
A contextual menu item was chosen. It reports the item the user picked from the menu built in ConstructContextualMenu.
This example removes the row the menu entry was built for:
If selectedItem.Tag.IsNull Then Return False Me.RemoveRowAt(selectedItem.Tag.IntegerValue) Return True
DesktopTable.Deactivated
Deactivated
The DesktopTable is deactivated. See the DesktopApplication and DesktopWindow Deactivated events.
In a multiple window interface, the Deactivated event fires when the parent window is deactivated because another window has been brought to the front or a window belonging to another app becomes frontmost. In a single window app, the Deactivated event fires when a window belonging to another app becomes frontmost.
This example stops a refresh timer while the window is in the background:
' Stop anything that only needs to run while the window is in front mRefreshTimer.RunMode = Timer.RunModes.Off
DesktopTable.DoublePressed
DoublePressed(row As Integer, column As Integer)
Double-click on a cell.
This example opens the record of the selected cell:
If Me.SelectedRowIndex <> DesktopTable.NoSelection Then ShowRecord(row, column) End If
DesktopTable.DragEnter
DragEnter(obj As DragItem, action As DragItem.Types) As Boolean
A drag entered the control. Return True to refuse the drag. The table only receives dragged data after one of the
Accept…Dropmethods was called.This example accepts folders only:
' Only take folders If obj.FolderItem = Nil Or Not obj.FolderItem.IsFolder Then Return True
DesktopTable.DragExit
DragExit(obj As DragItem, action As DragItem.Types)
A drag left the control. The pointer left the table again; the drop did not happen here.
This example clears the hint shown during the drag:
' Remove the hint shown while the drag was over the table StatusLabel.Text = ""
DesktopTable.DragOver
DragOver(x As Integer, y As Integer, obj As DragItem, action As DragItem.Types) As Boolean
A drag is moving over the control. It fires repeatedly while the pointer moves over the table. Return True to refuse the drop at that position.
This example refuses a drop over the header area:
' Refuse the drop over the header area If y < Me.HeaderHeight Then Return True
DesktopTable.DragOverRow
DragOverRow(x As Integer, y As Integer, obj As DragItem, action As Integer, ByRef row As Integer, ByRef parentRow As Integer, ByRef location As DesktopTable.DropLocations) As Boolean
row-aware drag feedback; adjust the ByRef values to move the drop target.
This example drops into a folder row and between the other rows:
' Drop into a folder row, between the others If Not Me.RowExpandableAt(row) Then location = DesktopTable.DropLocations.AfterRow Return False
DesktopTable.DragReorderRows
DragReorderRows(newPosition As Integer, parentRow As Integer) As Boolean
Rows are being reordered by drag; return True to handle it yourself.
This example moves the record along with its row:
' Move the record along with the row mRecords.AddAt(newPosition, mRecords(Me.SelectedRowIndex)) mRecords.RemoveAt(Me.SelectedRowIndex + If(newPosition < Me.SelectedRowIndex, 1, 0))
DesktopTable.DragRow
DragRow(drag As DragItem, row As Integer) As Boolean
The user started dragging row out of the table, which only happens while AllowRowDragging is on. Put the data into drag and return True to allow the drag.
This example puts the row's first cell into the drag and allows it:
drag.Text = Me.CellTextAt(row, 0) Return True
DesktopTable.DropObject
DropObject(obj As DragItem, action As DragItem.Types)
Something was dropped on the control. The drop was not aimed at a particular row. DropObjectOnRow reports one that was.
This example adds the dropped text as a new row:
If obj.TextAvailable Then Me.AddRow(obj.Text)
DesktopTable.DropObjectOnRow
DropObjectOnRow(x As Integer, y As Integer, obj As DragItem, action As Integer, row As Integer, parentRow As Integer, location As DesktopTable.DropLocations)
Something was dropped on a specific row. The values tell you which row was hit and whether the drop happened on it or between rows, so the data can be inserted at the right place.
This example inserts below the row, or replaces its text when dropped on it:
If Not obj.TextAvailable Then Return If location = DesktopTable.DropLocations.AfterRow Then Me.AddRowAt(row + 1, obj.Text) Else Me.CellTextAt(row, 0) = obj.Text End If
DesktopTable.FocusLost
FocusLost
The control lost keyboard focus. The table no longer receives keystrokes, and the selection is drawn in the inactive colour.
This example disables the actions that work on the selection:
' Grey out the actions that work on the selection DeleteButton.Enabled = False
DesktopTable.FocusReceived
FocusReceived
The control gained keyboard focus. The table now receives keystrokes, and the selection is drawn in the active colour.
This example enables them again to match the selection:
DeleteButton.Enabled = Me.SelectedRowCount > 0
DesktopTable.KeyDown
KeyDown(key As String) As Boolean
The user pressed key while the table has the focus. It fires before the table acts on the key: return True to keep the key to yourself, otherwise the arrow keys move the selection, Shift extends it in Multiple mode, and Home, End, Page Up and Page Down scroll.
This example removes the selected rows on Delete:
' Delete removes the selected rows If key.Asc = 8 Or key.Asc = 127 Then For i As Integer = Me.LastRowIndex DownTo 0 If Me.RowSelectedAt(i) Then Me.RemoveRowAt(i) Next Return True End If
DesktopTable.KeyUp
KeyUp(key As String)
The user released key while the table had the focus. It fires after the matching key press was dealt with and reports the key itself, not what the table did with it.
This example applies a filter once Return was released:
' Filter as the user types in a search field above the table If key = Chr(13) Then ApplyFilter(SearchField.Text)
DesktopTable.MenuBarSelected
MenuBarSelected
The menu bar is about to open. It fires just before a menu opens, so menu items can be enabled or disabled to match the current selection.
This example enables the Edit menu items that need a selection:
EditCopy.Enabled = Me.SelectedRowCount > 0 EditClear.Enabled = Me.SelectedRowCount > 0
DesktopTable.MouseDown
MouseDown(x As Integer, y As Integer) As Boolean
The user pressed the mouse button over the table, at x, y in the table's own coordinates. It fires before the table changes the selection or starts a drag; returning True takes the click, which is also what makes the following MouseDrag and MouseUp reach you.
This example claims the click on the icon column:
' Take the click on the icon column, and with it MouseDrag and MouseUp Var column As Integer = Me.ColumnFromXY(x, y) If column = 0 Then Return True
DesktopTable.MouseDrag
MouseDrag(x As Integer, y As Integer)
DesktopTable.MouseEnter
MouseEnter
Pointer entered the control. Use it to change the mouse cursor or to show information about what is under the pointer.
This example changes the mouse cursor over the table:
Me.MouseCursor = System.Cursors.FingerPointer
DesktopTable.MouseExit
MouseExit
Pointer left the control. Anything shown while the pointer was inside, such as a highlight of your own, belongs back to its normal state here.
This example restores the cursor and clears the status label:
Me.MouseCursor = Nil StatusLabel.Text = ""
DesktopTable.MouseMove
MouseMove(x As Integer, y As Integer)
Pointer moved. It fires while no mouse button is held down.
This example remembers the row under the pointer for a hover highlight:
' Highlight the row under the pointer Var row As Integer = Me.RowFromXY(x, y) If row <> mHotRow Then mHotRow = row Me.Refresh(False) End If
DesktopTable.MouseUp
MouseUp(x As Integer, y As Integer)
DesktopTable.MouseWheel
MouseWheel(x As Integer, y As Integer, deltaX As Integer, deltaY As Integer) As Boolean
The user turned the mouse wheel or scrolled on a trackpad over the table; deltaX and deltaY are the steps. It fires before the table scrolls, so returning True lets you scroll by yourself or keep the table where it is.
This example zooms with Command and the wheel instead of scrolling:
' Command + wheel zooms instead of scrolling If Keyboard.AsyncCommandKey Then Me.FontSize = Max(9, Me.FontSize + deltaY) Return True End If
DesktopTable.Opening
Opening
The control is being set up. The table is ready to be filled, so rows added here cost a single layout pass no matter how many there are.
This example sets up the columns and fills the table:
Me.ColumnCount = 2 Me.ColumnHeaderAt(0) = "Name" Me.ColumnHeaderAt(1) = "City" Me.ColumnWidths = "*,120" For Each r As Record In mRecords Me.AddRow(r.Name, r.City) Next
DesktopTable.PaintBackground
PaintBackground(g As Graphics)
Fires once per repaint, right after the list background is filled and before rows, grid and header.
gis the whole, unclipped control surface.This example paints the area behind the rows:
' A watermark behind the rows g.DrawingColor = Color.RGB(245, 245, 245) g.FillRectangle(0, 0, g.Width, g.Height) Return True
DesktopTable.PaintCellBackground
PaintCellBackground(g As Graphics, row As Integer, column As Integer) As Boolean
Draw the cell background yourself; return True to suppress the default. It fires once per visible cell per frame, before the selection and the cell content are drawn. Test the cheap condition first and leave the rest to the table.
This example draws every other row in a light grey:
' Stripes: test the cheap condition first, this fires once per visible cell If row Mod 2 = 0 Then Return False g.DrawingColor = Color.RGB(245, 245, 245) g.FillRectangle(0, 0, g.Width, g.Height) Return True
DesktopTable.PaintCellText
PaintCellText(g As Graphics, row As Integer, column As Integer, x As Integer, y As Integer) As Boolean
Draw the cell text yourself. The Graphics is clipped to the cell and x, y mark where the standard text would start. Return True to suppress it.
This example draws negative amounts right-aligned and in red:
' Negative amounts in red, right aligned If column <> 2 Then Return False Var amount As Double = Me.CellTextAt(row, column).Val If amount < 0 Then g.DrawingColor = Color.RGB(200, 0, 0) g.DrawText(amount.ToString("#,##0.00"), g.Width - g.TextWidth(amount.ToString("#,##0.00")) - 4, y) Return True
DesktopTable.PaintDisclosureWidget
PaintDisclosureWidget(g As Graphics, row As Integer, ByRef x As Integer, ByRef y As Integer, ByRef width As Integer, ByRef height As Integer) As Boolean
Draw or reposition the disclosure widget. Changing the passed values moves and resizes the widget without taking the drawing over; returning True draws it yourself. The rectangle is in the coordinates of the cell, and it is the rectangle the row is expanded and collapsed by: wherever the widget is drawn is where it is clicked.
The width also says how much room stays free before the cell text, so a widget widened where it stands pushes the text along with it. A widget that is moved does not: a handler that puts it at the far end of the cell needs nothing kept free at the start, so the text keeps the indent every other row has.
The event fires for every expandable row, including one whose first column is the anchor of a merge. The graphics carries the cell's own font.
This example moves the widget to the right and lets the table draw it:
' Move the widget a little to the right, but let the table draw it x = x + 4 Return False
DesktopTable.PaintHeaderBackground
PaintHeaderBackground(g As Graphics, column As Integer) As Boolean
Draw a header cell's background yourself. It fires once per visible header cell. A hidden column raises no paint event at all.
This example highlights the header of the sorting column:
If column <> Me.SortingColumn Then Return False g.DrawingColor = Color.RGB(226, 236, 250) g.FillRectangle(0, 0, g.Width, g.Height) Return True
DesktopTable.PaintHeaderContent
PaintHeaderContent(g As Graphics, column As Integer, x As Integer, y As Integer) As Boolean
Draw the header cell's content manually. The x, y values specify the starting point of the standard text.
This example draws the heading in bold capitals:
g.Bold = True g.DrawText(Me.ColumnHeaderAt(column).Uppercase, x, y) Return True
DesktopTable.PaintRowAction
PaintRowAction(g As Graphics, row As Integer, action As DesktopTableRowAction, pressed As Boolean) As Boolean
Draw one row-action button yourself.
gis clipped to the button, so(0,0)is its corner andg.Width/g.Heightits size.pressedis True while the mouse is held on it.This example draws a rounded button instead of the full-height default:
' A rounded button instead of the full-height default g.DrawingColor = If(pressed, Color.RGB(150, 30, 25), Color.RGB(217, 48, 37)) g.FillRoundRectangle(6, 6, g.Width - 12, g.Height - 12, 8, 8) g.DrawingColor = Color.White g.DrawText(action.Title, (g.Width - g.TextWidth(action.Title)) / 2, g.Height / 2 + g.FontAscent / 2) Return True
DesktopTable.PaintSortWidget
PaintSortWidget(g As Graphics, column As Integer, ByRef x As Integer, ByRef y As Integer, ByRef width As Integer, ByRef height As Integer) As Boolean
Draw or reposition the sort indicator. Independent of PaintHeaderContent - the standard indicator still draws even when the header's own text/background was handled.
This example shrinks the sort indicator and lets the table draw it:
' A smaller indicator, drawn by the table width = 8 height = 8 Return False
DesktopTable.RowActionSelected
RowActionSelected(row As Integer, action As DesktopTableRowAction)
The user picked a row action.
actionis theDesktopTableRowActionitself, soTagandTitleare both available. The panel is already closed.This example carries out the action the user picked:
Select Case action.Tag Case "delete" Me.RemoveRowAt(row) Case "unread" Me.CellBoldAt(row, 0) = True End Select
DesktopTable.RowCollapsed
RowCollapsed(row As Integer)
A row was collapsed. The children of a row are no longer visible. Whether they are also removed from the data is up to you.
This example frees the children that were loaded for the open row:
' Free the children that were only loaded for the open row RemoveChildrenOf(row)
DesktopTable.RowComparison
RowComparison(row1 As Integer, row2 As Integer, column As Integer, ByRef result As Integer) As Boolean
Custom sort comparison; set
resultto-1,0or1and return True. It is called while sorting, for every pair of rows the sort compares. A negative result puts row1 first, a positive one row2.This example sorts the amount column numerically instead of as text:
' Sort the amount column numerically instead of as text If column <> 2 Then Return False Var a As Double = Me.CellTextAt(row1, column).Val Var b As Double = Me.CellTextAt(row2, column).Val result = If(a < b, -1, If(a > b, 1, 0)) Return True
DesktopTable.RowExpanded
RowExpanded(row As Integer)
A row was expanded - the place to add its children. Children added here appear directly below the row. Loading them only now keeps a large tree cheap.
This example loads the children only when the row is opened:
' Load the children only now Var depth As Integer = Me.RowDepthAt(row) + 1 For Each child As Record In ChildrenOf(row) Me.AddRowAt(row + 1, depth, child.Name) Next
DesktopTable.Scrolled
Scrolled(x As Integer, y As Integer)
The view scrolled. It fires for every scroll step, from the scrollbars, the mouse wheel, the keyboard and from code.
This example keeps a second table in sync:
' Keep a second table in sync DetailTable.ScrollPosition = Me.ScrollPosition
DesktopTable.SelectionChanged
SelectionChanged
The selection changed. It fires once per change, no matter how many rows it affects.
This example follows the selection with a button and a detail view:
DeleteButton.Enabled = Me.SelectedRowCount > 0 If Me.SelectedRowIndex <> DesktopTable.NoSelection Then ShowRecord(Me.SelectedRowIndex) End If
Notes
Row actions
A horizontal two-finger swipe on a row reveals the actions returned by ApplyLeadingActionsForRow and ApplyTrailingActionsForRow. The events are raised once per gesture, so building the array there costs nothing per frame; returning an empty array leaves the gesture an ordinary scroll. A swipe only takes over once the content cannot scroll further that way.
Menu handlers
While the table has the focus it handles two standard Edit menu items itself. EditCopy copies the selected rows to the clipboard as text - one line per row, the visible columns separated by Tab - and EditSelectAll calls SelectAll when RowSelectionType is Multiple. Both require menu items named exactly that, with AutoEnable turned on.
Custom drawing
The paint events fire once per visible item per frame and all follow the same contract: the Graphics is already clipped to the item, so (0, 0) is its own corner, and returning True suppresses the built-in drawing. Test the cheap condition first - a table of 25 visible rows and 5 columns raises PaintCellBackground 125 times per frame.
Interfaces
This class implements the ListSelectionNotifier class interface.
Compatibility
Project Types |
Desktop |
Operating Systems |
All |