Class

ListBox (deprecated)


Warning

This item was deprecated in version 2021r3. Please use DesktopListBox as a replacement.

Description

The scrollable ListBox control is used to display one or more columns of information.

Properties

Name

Type

Read-Only

Shared

Active

Boolean

ActiveTextControl

TextEdit

AllowAutoDeactivate

Boolean

AllowAutoHideScrollbars

Boolean

AllowExpandableRows

Boolean

AllowFocusRing

Boolean

AllowResizableColumns

Boolean

AllowRowDragging

Boolean

AllowRowReordering

Boolean

AllowTabStop

Boolean

Bold

Boolean

CellAlignmentAt

Integer

CellAlignmentOffsetAt

Integer

CellBorderBottomAt

Integer

CellBorderLeftAt

Integer

CellBorderRightAt

Integer

CellBorderTopAt

Integer

CellCheckBoxValueAt

Boolean

CellTypeAt

Integer

ColumnAlignmentAt

Integer

ColumnAlignmentOffsetAt

Integer

ColumnAt

ListColumn

ColumnCount

Integer

ColumnSortDirectionAt

Integer

ColumnTypeAt

Integer

ColumnWidths

String

DefaultRowHeight

Integer

DropIndicatorVisible

Boolean

Enabled

Boolean

FontName

String

FontSize

Single

FontUnit

FontUnits

GridLinesHorizontalStyle

Integer

GridLinesVerticalStyle

Integer

Handle

Integer

HasBorder

Boolean

HasHeader

Boolean

HasHorizontalScrollbar

Boolean

HasVerticalScrollbar

Boolean

HeaderHeight

Integer

HeadingIndex

Integer

Height

Integer

Index

Integer

InitialValue

String

Italic

Boolean

LastAddedRowIndex

Integer

LastColumnIndex

Integer

LastRowIndex

Integer

Left

Integer

List

String

LockBottom

Boolean

LockLeft

Boolean

LockRight

Boolean

LockTop

Boolean

MouseCursor

MouseCursor

MouseX

Integer

MouseY

Integer

Name

String

PanelIndex

Integer

Parent

Control

RequiresSelection

Boolean

RowCount

Integer

RowHeight

Integer

RowSelectionType

Integer

Scope

Integer

ScrollPosition

Integer

ScrollPositionX

Integer

Selected

Boolean

SelectedRowCount

Integer

SelectedRowIndex

Integer

SelectedRowValue

String

SortingColumn

Integer

TabIndex

Integer

Tooltip

String

Top

Integer

Transparent

Boolean

TrueWindow

Window

Underline

Boolean

Visible

Boolean

Width

Integer

Window

Window

Methods

Name

Parameters

Returns

Shared

AcceptFileDrop

FileType As String

AcceptPictureDrop

AcceptRawDataDrop

Type As String

AcceptTextDrop

AddAllRows

items() As String

AddExpandableRow

text As String

AddExpandableRowAt

index As Integer, text As String

AddRow

ParamArray Item As String

AddRowAt

RowNumber As Integer, Item As String, [Indent As Integer]

CellBold

RowNumber As Integer, ColumnNumber As Integer

Boolean

CellCheckBoxStateAt

Row As Integer, Column As Integer

CheckBox

CellItalic

RowNumber As Integer, ColumnNumber As Integer

Boolean

CellTagAt

Row As Integer, Column As Integer

Variant

CellToolTipAt

RowNumber As Integer, ColumnNumber As Integer

String

CellUnderline

RowNumber As Integer, ColumnNumber As Integer

Boolean

CellValueAt

Close

ColumnFromXY

X As Integer, Y As Integer

Integer

ColumnSortTypeAt

Column As Integer

ListBox

ColumnTagAt

Column As Integer

Variant

DrawInto

g As Graphics, x As Integer, y As Integer

EditCellAt

Row As Integer, Column As Integer

ExpandableRowAt

row As Integer

Boolean

HeaderAt

String

Invalidate

[EraseBackground As Boolean]

InvalidateCell

Row As Integer, Column As Integer

PressHeader

Column As Integer

Refresh

eraseBackground As Boolean

RemoveAllRows

RemoveRowAt

RowNumber As Integer

RowDepthAt

row As Integer

Integer

RowExpandedAt

RowNumber As Integer

Boolean

RowFromXY

X As Integer, Y As Integer

Integer

RowImageAt

RowNumber As Integer

Picture

Rows

ListBoxRow

RowTagAt

Row As Integer

Variant

SetFocus

Sort

Events

Name

Parameters

Returns

CellAction

Row As Integer, Column As Integer

CellBackgroundPaint

g As Graphics, Row As Integer, Column As Integer

Boolean

CellClick

Row As Integer, Column As Integer, X As Integer, Y As Integer

Boolean

CellGotFocus

Row As Integer, Column As Integer

CellKeyDown

Row As Integer, Column As Integer, Key As String

Boolean

CellLostFocus

Row As Integer, Column As Integer

CellTextChange

Row As Integer, Column As Integer

CellTextPaint

g As Graphics, Row As Integer, Column As Integer, x As Integer, y As Integer

Boolean

Change

Close

CollapseRow

Row As Integer

CompareRows

Row1 As Integer, Row2 As Integer, Column As Integer, ByRef Result As Integer

Boolean

ConstructContextualMenu

Base As MenuItem, x As Integer, y As Integer

Boolean

ContextualMenuAction

HitItem As MenuItem

Boolean

DisclosureWidgetPaint

g As Graphics, row As Integer, ByRef x As Integer, ByRef y As Integer, ByRef width As Integer, ByRef height As Integer

DoubleClick

DragEnter

obj As DragItem, Action As Integer

Boolean

DragExit

obj As DragItem, Action As Integer

DragOver

x As Integer, y As Integer, obj As DragItem, Action As Integer

Boolean

DragOverRow

x As Integer, y As Integer, obj As DragItem, action As Integer, ByRef row As Integer, ByRef parentRow As Integer, ByRef location As ListBox

DragReorderRows

NewPosition As Integer, ParentRow As Integer

Boolean

DragRow

Drag As DragItem, Row As Integer

Boolean

DropObject

Obj As DragItem Action As Integer

DropObjectOnRow

x As Integer, y As Integer, obj As DragItem, action As Integer, row As Integer, parentRow As Integer, location As ListBox

EnableMenuItems

ExpandRow

Row As Integer

GotFocus

HeaderBackgroundPaint

g As Graphics, column As Integer

HeaderContentPaint

g As Graphics, column As Integer

HeaderPressed

Column As Integer

Boolean

KeyDown

Key As String

Boolean

KeyUp

Key As String

LostFocus

MouseDown

x As Integer, y As Integer

Boolean

MouseDrag

x As Integer, y As Integer

MouseEnter

MouseExit

MouseMove

X As Integer, Y As Integer

MouseUp

x As Integer, y As Integer

MouseWheel

X As Integer, Y As Integer, DeltaX As Integer, DeltaY As Integer

Boolean

Open

SortColumn

Column As Integer

Boolean

Constants

The following class constants of the DragItem class can be used with HeaderAt to specify that a method should apply to all columns or rows rather than a specific column or row.

Class Constant

AllColumns

AllRows

Enumerations

ListBox.Alignments

Alignments

Specifies all possible cell value alignments.

Enum

Description

Default

The OS-specific default alignment.

Left

The cell value will be left-justified.

Center

The cell value will be center-aligned.

Right

The cell value will be right-justified.

Decimal

The cell value will be aligned to the decimal point.

ListBox.Borders

Borders

Specifies all possible border-styles types for cells.

Enum

Description

Default

The type of border unless otherwise specified. Default is None.

None

No border line is drawn.

ThinDotted

A thin, dotted line.

ThinSolid

A thin, solid line.

ThickSolid

A thick, solid line.

DoubleThinSolid

Two thin, solid lines.

ListBox.CellTypes

CellTypes

Used to indicate the type of cell.

Enum

Description

Default

The default type for a cell. The default is Normal.

Normal

A cell that can't be edited directly by the end user.

CheckBox

The cell contains only a checkbox.

TextField

A cell that can be edited by the end user allowing a single line of text.

TextArea

A cell that can be edited by the end user allowing multiple lines of text.

ListBox.DropLocations

DropLocations

Used to indicate where on the ListBox an object was dropped.

Enum

Description

OnRow

The drop is occurring on the row itself.

AfterRow

The drop is occurring between rows, after the row specified. The row can be in the range of [-1, RowCount-1] and specifying -1 will insert it at the top of all the rows. This value will also be RowCount-1 if the user drags below the item list.

AfterAllRows

The drop is occurring after all rows in the list.

OnRow

The drop is occurring on the entire control, not on a particular row. This matches the previous behavior.

ListBox.RowSelectionTypes

RowSelectionTypes

Used to indicate if the selection can be one or more rows.

Enum

Description

Single

Only one row is selectable at a time.

Multiple

Any number of rows may be selected at the same time.

ListBox.SortDirections

SortDirections

Used to indicate if a column's sorting should be ascending, descending or none.

Enum

Description

Descending

Rows are sorted in reverse alphabetical order.

None

The rows are unsorted.

Ascending

The rows are sorted in standard alphabetical order.

ListBox.SortTypes

SortTypes

Specifies whether or not a listbox column is sortable by the end user.

Enum

Description

Sortable

The column header includes a widget allowing the end user to sort the contents of the column.

Unsortable

The column header does not include a sorting widget, preventing the end user form sorting the column contents.

Property descriptions


ListBox.Active

Active As Boolean

Indicates whether the RectControl is active.

This property is read-only.

Active is False when the RectControl's window is not in the foreground. When a Window is deactivated, its controls are automatically deactivated unless AutoDeactivate is set to False.


ListBox.ActiveTextControl

ActiveTextControl As TextEdit

The TextArea or TextField that the ListBox uses for its editable cell operations.

This property is read-only.

The TextEdit can be either a TextField or a TextArea control. To specify which one, the ListBox uses the two following ListBox values:

ListBox.CellTypes.TextArea
ListBox.CellTypes.TextField

For example,

ListBox1.CellTypeAt(1,0) = ListBox.CellTypes.TextField

To get this TextField, you must put the cell into the Inline Editable mode via the CellTypeAt or ColumnTypeAt properties and make it editable by calling the EditCellAt method. You can use this property to set or get the text of the ListBox cell (using SelectedText), set the selection, or change other properties of the ListBox's TextField.


ListBox.AllowAutoDeactivate

AllowAutoDeactivate As Boolean

Determines whether the control should be deactivated (on macOS) when the parent window is deactivated. The default is True.


ListBox.AllowAutoHideScrollbars

AllowAutoHideScrollbars As Boolean

Controls whether scrollbars are shown when scrolling is not necessary to bring additional text into view. The default is True.

The vertical scroll does not appear until there are more items in the ListBox than can be viewed at once. If AllowAutoHideScrollbars is False, then inactive scrollbars are shown until they are needed to bring additional text into view. AllowAutoHideScrollbars can be set at design time or runtime.

This example turns off AllowAutoHideScrollbars.

Me.AllowAutoHideScrollbars = False

ListBox.AllowExpandableRows

AllowExpandableRows As Boolean

Allows for disclosure triangles for rows added via the AddExpandableRow method.

On Windows, plus and minus signs are used instead of disclosure triangles.


ListBox.AllowFocusRing

AllowFocusRing As Boolean

If True, the control indicates when it has the focus by drawing a ring around its border. If False, the appearance of the control does not change when it has the focus.


ListBox.AllowResizableColumns

AllowResizableColumns As Boolean

If True, the user can resize columns by moving the pointer over a column divider and dragging to the left or right.

This property is read-only.

When the pointer is over a divider, it changes to an East-West Splitter pointer to indicate that the user can drag the divider. If AllowResizableColumns is False, the pointer does not change its shape.

This example enables the resizable feature.

Me.AllowResizableColumns = True

ListBox.AllowRowDragging

AllowRowDragging As Boolean

Allows rows to be dragged.

The following example allows the user to drag one row from ListBox1 to ListBox2. ListBox1 has its AllowRowDragging property set to True and its RowSelectionType property set to zero (Single). Its DragRow event handler is as follows:

Function DragRow(drag As DragItem, row As Integer) As Boolean
  drag.Text = Me.List(row)
  Return True ' allow the drag

ListBox2's Open event handler has the line:

Me.AcceptTextDrop

Its DropObject event handler is this:

Sub DropObject(obj As DragItem)
  Me.AddRow(obj.Text) ' adds the dropped text as a new row

The following example allows the user to drag more than one row from ListBox1 to ListBox2. The dragged rows are added to the end of the list.

ListBox1 has its AllowRowDragging property set to True, enabling items in its list to be dragged, and its RowSelectionType property set to 1 (Multiple row selection). Its DragRow event handler is as follows:

Function DragRow (drag As DragItem, row As Integer) As Boolean
  Var nRows, i As Integer
  nRows = Me.RowCount - 1
  For i = 0 To nRows
    If Me.Selected(i) Then
      drag.AddItem(0, 0, 20, 4)
      drag.Text = Me.List(i) ' get text
    End If
  Next
  Return True ' allow the drag
End Function

It uses the AddItem method of the DragItem to add an additional item to the DragItem each selected row. The DropObject event handler then cycles through all items to retrieve all dragged rows.

ListBox2 has the following line of code in its Open event handler. It permits it to receive dragged text.

Me.AcceptTextDrop

Its DropObject event handler checks to see if the dragged object is text; if it is, it adds a row to the end of the list and assigns the text property of the dragged object to the new row: It loops through all items in the DragItem until NextItem returns False.

Sub DropObject(obj As DragItem)
  Do
    If obj.TextAvailable Then
      Me.AddRow(obj.Text)
    End If
  Loop Until Not obj.NextItem
End Sub

ListBox.AllowRowReordering

AllowRowReordering As Boolean

If True, you can reorder rows within the ListBox by dragging rows.

An insertion line indicator appears when dragging within the ListBox to provide you with visual feedback as to where the row would be dropped if you release the mouse button. .. note:: You cannot drag rows on a ListBox with expandable rows (hierarchical) and as a result, setting this property to True has no effect.

This example enables the drag reorder feature.

Me.AllowRowReordering = True

ListBox.AllowTabStop

AllowTabStop As Boolean

If True, the RectControl 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 RectControl 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

ListBox.Bold

Bold As Boolean

If True, applies the bold style to the control's caption and/or its text content if any.

Mac apps can only display font styles that are available. You cannot force a font to display in bold or italic if it does not have bold or italic variations available. In this situation, the Bold property will not affect the font.


ListBox.CellAlignmentAt

CellAlignmentAt As Integer

Aligns the specified cell. Row and Column are zero-based.

You specify the alignment via ListBox.

Decimal aligns the decimal separator to the right edge of the cell. You need to use CellAlignmentOffsetAt or ColumnAlignmentOffsetAt to move the data into the column.

Listbox1.CellAlignmentAt(1,1) = ListBox.Alignments.Right

ListBox.CellAlignmentOffsetAt

CellAlignmentOffsetAt As Integer

The value is the distance in points from the right edge of the cell. Row and Column are zero-based. This property overrides ColumnAlignmentOffsetAt for that cell.

Any value specified here is applied to the value used for ColumnAlignmentOffset.

This code is applied to a column that is right-aligned and moves the contents of a cell 10 points to the left.

Me.CellAlignmentOffsetAt(1, 3) = -10

ListBox.CellBorderBottomAt

CellBorderBottomAt As Integer

Sets the bottom border of the cell designated by Row, Column to a rule style. Row and Column are zero-based.

You specify the Border via ListBox.

The following example sets the bottom border of a cell to Thin Solid.

ListBox1.CellBorderBottomAt(1, 1) = ListBox.Borders.ThinSolid

ListBox.CellBorderLeftAt

CellBorderLeftAt As Integer

Sets the left border of the cell designated by Row, Column to a rule style. Row and Column are zero-based.

You specify the Border via ListBox.

The following example sets the border of a cell to Thin Solid.

ListBox1.CellBorderLeftAt(1, 1) = ListBox.Borders.ThinSolid

ListBox.CellBorderRightAt

CellBorderRightAt As Integer

Sets the right border of the cell designated by Row, Column to a rule style. Row and Column are zero-based.

You specify the Border via ListBox.

The following example sets the right border of a cell to Thin Solid.

ListBox1.CellBorderRightAt(1, 1) = ListBox.Borders.ThinSolid

ListBox.CellBorderTopAt

CellBorderTopAt As Integer

Sets the top border of the cell designated by Row, Column to a rule style. Row and Column are zero-based.

You specify the Border via ListBox.

The following example sets the top border of a cell to Thin Solid.

For example:

ListBox1.CellBorderTopAt(1, 1) = ListBox.Borders.ThinSolid

ListBox.CellCheckBoxValueAt

CellCheckBoxValueAt As Boolean

Checks or unchecks the checkbox in the passed cell. Row and Column are zero-based.

Setting CellCheckBoxValueAt to True checks the checkbox.


ListBox.CellTypeAt

CellTypeAt As Integer

Sets the type of the passed cell. Row and Column are zero-based.

The cell type can be set with ListBox.

This code shows a checkbox in a single cell:

ListBox1.CellTypeAt(0, 4) = Listbox.CellTypes.Checkbox ' Cell in the 1st row, 5th column now shows a checkbox

To set or use the value of the Cell's checkbox see both the CellCheckBoxValueAt property (boolean) and CellCheckBoxStateAt method (CheckedUncheckedIndeterminate). This code uses CellCheckboxStateAt to set the cell to be checked:

ListBox1.CellCheckBoxStateAt(0, 4) = CheckBox.VisualStates.Checked

ListBox.ColumnAlignmentAt

ColumnAlignmentAt As Integer

Aligns the specified column. The first column is numbered zero.

You specify the alignment via the ListBox enumeration.

Set right alignment:

ListBox1.ColumnAlignmentAt(1) = ListBox.Alignments.Right

ListBox.ColumnAlignmentOffsetAt

ColumnAlignmentOffsetAt As Integer

Modifies the alignment point and is especially useful for decimal alignment. The first column is numbered zero.

The value is the distance in points from what is specified for the column alignment.

For right alignment, a negative value moves the decimal separator to the left, i.e., into the body of the column. See the example in the Notes subsection "Decimal Alignment."

ListBox columns are zero-based.

This code sets the offset in a right-aligned column by 10 points.

Me.ColumnAlignmentOffsetAt(2) = -10

ListBox.ColumnAt

ColumnAt As ListColumn

Enables you to access the ListColumn properties of the specified column. The first column is numbered zero.

Use ListBox.AllColumns to refer to all columns.


ListBox.ColumnCount

ColumnCount As Integer

The number of columns the ListBox contains. The maximum number of columns is 256.

Setting this value higher than 255, will result in the ColumnCount being set to 256.

Adding a column to ListBox1 and setting the widths of the columns to 50 and 65 pixels, respectively:

ListBox1.ColumnCount = 2
ListBox1.ColumnWidths = "50,65"

Setting the number of columns of ListBox1 to three and setting the widths of the columns to 60%, 20% and 20% respectively:

ListBox1.ColumnCount = 3
ListBox1.ColumnWidths = "60%,20%,20%"

ListBox.ColumnSortDirectionAt

ColumnSortDirectionAt As Integer

Used to get or set the sort direction for the passed column. The first column is numbered zero.

You set the sort direction using ListBox.

This example sets the sort direction for a column.

ListBox1.ColumnSortDirectionAt(2) = ListBox.SortDirections.Descending

ListBox.ColumnTypeAt

ColumnTypeAt As Integer

Sets the type for the passed column. The first column is numbered zero.

Column types are set using ListBox.

The following makes a column editable:

lb1.ColumnTypeAt(1) = ListBox.CellTypes.TextField

Disclosure triangles don't work in hierarchical ListBoxes if the CellType is TextField or TextArea. ColumnTypeAt can be overridden by CellType.

The following example makes a column a checkbox column and sets two of the values:

Me.ColumnTypeAt(4) = Listbox.CellTypes.Checkbox
Me.CellCheckBoxStateAt(0, 4) = CheckBox.VisualStates.Indeterminate
Me.CellCheckBoxStateAt(1, 4) = Checkbox.VisualStates.Checked

.


ListBox.ColumnWidths

ColumnWidths As String

A list of comma-separated values, with each value controlling the width of the associated column. A value can be an absolute value (in points), a percentage, a relative length expressed as i* where i is an integer, or an "*" that indicates "fill in the remaining width." If you use percentages, you can use non-integer values to specify fractions of a percent, e.g., 43.52%. The percentage value can be greater than 100%.

If you use points, the last column doesn't grow to the size of the rest of the ListBox. You should set the width of the last column to "*" and it will automatically take up the remaining width of the ListBox.

Without any column width specifications, the headers will be divided evenly. If there are fewer column widths specified than the total number of columns, the remaining columns will divide up the remaining width equally.

An element with a length of "3*" will be allotted three times the space of an element with length "1*". The value "*" is equivalent to "1*" and can be used to mean "fill the remaining space."

You can use a mixture of points, percentages, and relative lengths. Column widths specified in pixels are guaranteed to have the specified width. Column widths specified in percentages are guaranteed to have that percentage of the visible width of the ListBox. The column widths specified using the * divide up the remaining width proportionally. For example, if there are four columns, the specification 20, 20%, , 2 gives 20 points to the first column 20% of the total to the second column, and the last two columns divide up the remaining width in the ratio of 1:2, with the last column getting any remaining fractional pixels.

Unrecognized or unsupported expressions (e.g. '2@')for the column width properties will result in an UnsupportedFormatException. The message of this exception describes in English what went wrong.

Resizing a column will resize the value of the expression. If you resize the ListBox, both the percentage and relative lengths recompute their actual widths. There are two resizing "modes"; see notes.

Header End caps are added for any additional unused space if headers are used. Header end caps do nothing when clicked.

Adding a column to ListBox1 and setting the widths of the columns to 50 and 65 points, respectively:

ListBox1.ColumnCount = 2
ListBox1.ColumnWidths = "50,65"

Setting the number of columns of ListBox1 to three and setting the widths of the columns to 60%, 20% and 20% respectively:

ListBox1.ColumnCount = 3
ListBox1.ColumnWidths = "60%,20%,20%"

If ListBox1 is 100 pixels wide and has three columns, the following code will set the columns widths as indicated but the last column will only be 10 points wide instead of 20:

ListBox1.ColumnWidths = "60,30,20"

If ListBox1 is 100 points wide and has three columns, the following code will set the columns widths but the last column will not be displayed:

ListBox1.ColumnWidths = "60,40,20"

ListBox.DefaultRowHeight

DefaultRowHeight As Integer

Determines the height of every row in the ListBox in points. Every row in the ListBox is always the same height.

Use a value of -1 to have the height automatically determined by the current font size.

This example increases the default row height.

Me.DefaultRowHeight = 35

ListBox.DropIndicatorVisible

DropIndicatorVisible As Boolean

Determines whether or not the drop indicators appears. This property changes the appearance of the ListBox. It does not prevent the new events from firing.


ListBox.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. Its caption is grayed out.

Me.Enabled = False

ListBox.FontName

FontName As String

Name of the font used to display text.

You can enter any font that is installed on the computer or the names of the two metafonts, "System" and "SmallSystem".

The System font is the font used by the system software as its default font. Different operating systems use different default fonts. If the system software supports both a large and small System font, you can also specify the "SmallSystem" font as your TextFont.

On macOS, "SmallSystem" specifies the OS's smaller system font and may make the control smaller in size as well. On Windows and Linux, "SmallSystem" is the same as "System".

This code sets the FontName property.

Me.FontName = "Helvetica"

ListBox.FontSize

FontSize As Single

Size of the font used to display text.

If you enter zero as the FontSize, your app will use the font size that works best for the platform on which it is running.

This code sets the font size to 16.

Me.FontSize = 16

ListBox.FontUnit

FontUnit As FontUnits

The units in which FontSize is measured.


ListBox.GridLinesHorizontalStyle

GridLinesHorizontalStyle As Integer

Draws horizontal lines between rows in the selected style.

The style for the borders is selected using ListBox.

This example sets the gridlines to Thin Solid. The example is in the Open event of the ListBox.

Me.GridLinesHorizontalStyle = ListBox.Borders.ThinSolid

ListBox.GridLinesVerticalStyle

GridLinesVerticalStyle As Integer

Draws vertical lines between columns based on the selected style.

The style for the borders is selected using ListBox.

This example sets the vertical lines to Thin Solid. The code is in the Open event of the control.

Me.GridLinesVerticalStyle = ListBox.Borders.ThinSolid

ListBox.Handle

Handle As Integer

Returns a handle to the control.

This property is read-only.

For interfacing with Mac APIs using Declare).

On Windows returns the HWND of the control.

On Linux it returns a GtkWidget.

The following gets a handle to the control.

Var i As Integer = Me.Handle

ListBox.HasBorder

HasBorder As Boolean

Indicates whether or not the border is visible.


ListBox.HasHeader

HasHeader As Boolean

If True, a row of column headers is added to the ListBox. The user can sort the column by clicking the heading if ColumnSortDirectionAt is true not set to None for that column.

The following example shows the Headers row. The code is in the Open event of the control.

Me.HasHeader = True

ListBox.HasHorizontalScrollbar

HasHorizontalScrollbar As Boolean

If True, adds a horizontal scrollbar to the ListBox.

The horizontal scrollbar only appears if the sum of the widths of the columns exceeds the width of the ListBox itself. If the widths of the columns is less than (or matches) the width of the ListBox, then no horizontal scrollbar appears.

The position of the thumb is indicated by ScrollPositionX. It is used to scroll the ListBox horizontally without a separate Scrollbar control.


ListBox.HasVerticalScrollbar

HasVerticalScrollbar As Boolean

If True, adds a vertical scrollbar to the ListBox. The position of the thumb is indicated by ScrollPosition. The default is True.


ListBox.HeaderHeight

HeaderHeight As Integer

The height of the header row in pixels.

This example displays the height of the header row. It is in the Action event of a button control.

Var h As Integer = Listbox1.HeaderHeight

ListBox.HeadingIndex

HeadingIndex As Integer

Allows you to get and set the sort column in a ListBox. The first column is numbered zero.

Using this property sets the sort direction indicator in the header.

You can also sort a ListBox by using the SortedColumn property to set the sort column and the ColumnSortDirection property to set the direction of the sort. Then call the Sort method to do the sort.

This code in the Open event of a ListBox sorts on the first column:

Me.SortedColumn = 0
Me.ColumnSortDirectionAt(0) = ListBox.SortDirections.Ascending
Me.HeadingIndex = 0
Me.Sort

ListBox.Height

Height As Integer

The height (in points) of the control.

This example sets the height of the control to 100:

Me.Height = 100

ListBox.Index

Index As Integer

If the control is used in a control set, this specifies the control's index in the set.

This property is read-only.

The control set is often used to manage a group of RadioButtons since a single RadioButton in a window doesn't make much sense. Most typically, you create an instance of the RadioButton, assign 0 to its Index property, and then duplicate it. This increments the value of Index for each new instance but retain the original control's name.

To determine which RadioButton the user clicked, use the Action event handler of the control set. The parameter Index contains the value of Index for the RadioButton that was clicked. The event handler is this:

Sub Action(Index As Integer)
  Label1.Text = "You chose radio button " + index.ToString + "."
End Sub

To set a RadioButton in a control set, you use its Index property to refer to the RadioButton whose value you want to set. For example, the following line selects the second RadioButton from code:

RadioButton1(1).Value = True ' 0-based

ListBox.InitialValue

InitialValue As String

A list of the default items separated by returns.

If the ListBox has more than one column (ColumnCount > 1), separate column entries with Tabs within each row. If HasHeading is True, the first row of InitialValue is assumed to be the column headings -- unless the Heading array is also specified.


ListBox.Italic

Italic As Boolean

If True, applies the italic style to the control's caption and/or its text content if any.

Mac apps can only display font styles that are available. You cannot force a font to display in bold or italic if it does not have bold or italic variations available. In this situation, the Italic property will not affect the font.


ListBox.LastAddedRowIndex

LastAddedRowIndex As Integer

The number of the last row added with the AddRow, AddExpandableRow, or AddRowAt method. LastAddedRowIndex is zero-based. If no rows have been added, LastAddedRowIndex will be the ListBox.None constant (-1). Use this to get the row number when getting or setting values in a multi-column ListBox. See the section on Multi-column listboxes in the Notes section.

This property is read-only.

This example project consists of a two-column ListBox and two TextFields for the entry of first and last names. A PushButton creates a new row in the ListBox and adds the contents of the TextFields to the ListBox.

PeopleList.Addrow("")
PeopleList.CellValueAt(PeopleList.LastAddedRowIndex, 0) = FirstNameField.Value
PeopleList.CellValueAt(PeopleList.LastAddedRowIndex, 1) = LastNameField.Value
PeopleList.SelectedIndex = PeopleList.LastAddedRowIndex ' select the newly added row
FirstNameField.SetFocus

This code asks the user to add a row if they have not yet done so:

If ListBox1.LastAddedRowIndex = ListBox.None then
 System.Beep
 MessageBox("Please add a row to continue.")
End If

ListBox.LastColumnIndex

LastColumnIndex As Integer

The number of the last column of the ListBox. Because the ListBox is zero-based, this value will be 1 less than the ListBox.

This property is read-only.


ListBox.LastRowIndex

LastRowIndex As Integer

The number of the last row of the ListBox. Because the ListBox is zero-based, this value will be 1 less than the ListBox.

This property is read-only.


ListBox.Left

Left As Integer

The left side of the control in local coordinates (relative to the window).

The following example moves the control 100 points from the left side of the window:

Me.Left = 150

ListBox.List

List As String

The list of items. List takes one parameter, the row index. The first row is numbered zero. Use it to get or set the contents of that cell, or, in multi-column ListBoxes, the contents of the first column.


ListBox.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

ListBox.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.

Beginning with version 2009r5, 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

ListBox.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

ListBox.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.

Beginning with version 2009r5, 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

ListBox.MouseCursor

MouseCursor As MouseCursor

The cursor to be displayed while the mouse is within the control and both the DesktopApplication and Window class's MouseCursor properties are Nil.

If the DesktopApplication class's MouseCursor property is not Nil or the Window'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 Macintosh, you can also obtain a MouseCursor from a resource file.

This line in the Open event of the control sets the default cursor to the finger pointer.

Me.MouseCursor = System.Cursors.FingerPointer

ListBox.MouseX

MouseX As Integer

The X coordinate of the mouse (points). Measured from the top-left corner of the control.

This property is read-only.

This code is in the MouseDown event of a TextField and displays the X-coordinate at the point of the MouseDown event.

Me.Value = Str(Me.MouseX)

ListBox.MouseY

MouseY As Integer

The Y coordinate of the mouse (points). Measured from the top-left corner of the control.

This property is read-only.

This code is in the MouseDown event of a TextField and displays the Y-coordinate at the point of the MouseDown event.

Me.Value = Str(Me.MouseY)

ListBox.Name

Name As String

The name of the control. Set the name of the control in the Inspector.

This property is read-only.


ListBox.PanelIndex

PanelIndex As Integer

If the control has been placed on a TabPanel or PagePanel 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 TabPanel or PagePanel control, it returns the panel number. If the control is not on a PagePanel or TabPanel, 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 PagePanel.

This code displays the panel index of the control that is on the page.

Label3.Value = Str(Me.PanelIndex)

ListBox.Parent

Parent As Control

Used to get and set the control's parent control or window.

Returns Nil if the parent is the window. Assign Nil to make the control's parent the window, even if it is enclosed by another control. The child control's behavior in the IDE will reflect the parent's state. 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

ListBox.RequiresSelection

RequiresSelection As Boolean

If True, users will not be able to deselect the last row by clicking below the last visible row or by dragging. You can still deselect the last row by setting the SelectedRowIndex property to ListBox.NoSelection.


ListBox.RowCount

RowCount As Integer

The number of rows in the ListBox.

This property is read-only.


ListBox.RowHeight

RowHeight As Integer

Gets the ListBox row height. All rows in a ListBox are always the same height, which you can change using DefaultRowHeight.

This property is read-only.


ListBox.RowSelectionType

RowSelectionType As Integer

Indicates the type of row selection allowed via mouse gestures.

The type of allowed row selection is set via ListBox.

The default is single-row selection. If multiple row selection is on, a ListBox will handle Edit > Select All menu item commands by default as long as the Select All menu item is named EditSelectAll.


ListBox.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.

If the Scope of a control is set to Private, it cannot be accessed from outside its parent window.


ListBox.ScrollPosition

ScrollPosition As Integer

Zero-based index of the top visible row in the ListBox.

Read ScrollPosition to determine the top visible row; write to ScrollPosition to scroll the ListBox. When the scrollbar thumb is scrolled to the bottom, ScrollPosition cannot be incremented any further.


ListBox.ScrollPositionX

ScrollPositionX As Integer

Zero-based index of the horizontal position of the ListBox.


ListBox.Selected

Selected As Boolean

Gets or sets the selection status of the passed Row. Row is zero-based.

Selected is True if the row passed is selected. This property can be used to determine if the row is selected and to select the row. For example,

Listbox1.Selected(1) = True  //selects the second item in the first column.

In order to select multiple row, the SelectionType must be set to Multiple. This code selects only the even-numbered rows:

ListBox1.ListIndex = -1 ' Deselect all rows

For i As Integer = 0 To ListBox1.LastRowIndex
  If i Mod 2 = 0 Then
    ListBox1.Selected(i) = True
  End If
Next

If you allow the ListBox to have multiple items selected (see SelectionType), you may want to establish a list of all the rows selected. The following example shows how to achieve that. The ListBox is named ListBox1.

Var selectedRows() As Integer ' Will hold the index of each selected row

For row As Integer = 0 To ListBox1.LastRowIndex
  If ListBox1.Selected(row) Then
    selectedRows.AddRow(row) ' This row is selected
  End If
Next

ListBox.SelectedRowCount

SelectedRowCount As Integer

The number of rows selected (highlighted).

This property is read-only.


ListBox.SelectedRowIndex

SelectedRowIndex As Integer

The number of the selected row.

If no item is selected, SelectedRowIndex returns ListBox.NoSelection. If the ListBox is in multiple-row selection mode, then the number of the lowest selected row is returned. For example, if rows 1, 3, and 4 are selected, SelectedRowIndex returns 1.

You can put the ListBox into multiple-row selection mode by changing the RowSelectionType property.

The following code in the Change event handler displays the text in the first column of the selected row:

If Me.SelectedRowIndex >= 0 Then
  MessageBox(Me.CellValueAt(Me.SelectedRowIndex, 0))
End If

The following code displays a message if no row is selected:

If ListBox1.SelectedRowIndex = ListBox.NoSelection Then
  MessageBox("Please select a row first.")
End If

ListBox.SelectedRowValue

SelectedRowValue As String

The value of the currently selected item.

In the case of multi-column ListBoxes, the value of the cell in the first column is returned.


ListBox.SortingColumn

SortingColumn As Integer

Gets or sets the current sort column but doesn't do the sort. The first column is numbered zero. If no column is sorted then it returns -1. Call the Sort method to sort the ListBox based on the values of SortingColumn and ColumnSortDirectionAt.

The following code in the Pressed event of a Pushbutton asks the user to sort on a column if the ListBox is not sorted by any column:

If Listbox1.SortingColumn = ListBox.None then
 System.Beep
 MessageBox("Please sort the rows by one of the columns.")
End If

ListBox.TabIndex

TabIndex As Integer

The RectControl's position in the Tab Order. It is 0-based. A TabIndex of 0 is the first RectControl to get the focus.

On the Mac you need Full Keyboard Access turned on in System Preferences (Keyboard->Shortcuts) in order to manually set focus to non-text controls.

This example sets the control's TabIndex.

Me.TabIndex = 2

ListBox.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 BevelButton that has an icon.

Me.CaptionAlignment = 0 ' left
Me.CaptionDelta = 10
Me.Tooltip = "Click to bark."

Me.Icon = Woof ' added to the project
Me.CaptionPosition = 2

ListBox.Top

Top As Integer

The top of the control in local coordinates (relative to the window).

This example sets the top of the control to 140 points from the top of the window:

Me.Top = 140

ListBox.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.


ListBox.TrueWindow

TrueWindow As Window

Returns a reference to the actual enclosing Window.

This property is read-only.

TrueWindow walks up the window hierarchy and finds the actual enclosing window regardless of how deeply nested the RectControl or DesktopContainer hierarchy is.

Window also has a TrueWindow property.

This example accesses the TrueWindow and displays its Title property in a TextField.

TextField1.Text = Me.TrueWindow.Title

ListBox.Underline

Underline As Boolean

If True, applies the underline style to the control's caption and/or its text content if any.


ListBox.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 in the DisclosureTriangle Action event handler displays or hides a ListBox on the window:

ListBox1.Value = Me.Visible

ListBox.Width

Width As Integer

The width (in points) of the control.

The following example resizes the control:

Me.Width = 200

ListBox.Window

Window As Window

The control's parent window.

This property is read-only.

This code gets the parent window's Title property.

TextField1.Text = Me.Window.Title

Method descriptions


ListBox.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 Open event of an ImageWell 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 just folders (and not files), you can put this code in the DragEnter event:

If Not obj.FolderItem.IsFolder Then Return True

ListBox.AcceptPictureDrop

AcceptPictureDrop

Permits pictures to be dropped on the control.

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 Open event of the control itself. For example, the line:

Me.AcceptPictureDrop

in the Open 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.

Canvas.Open:

Me.AcceptPictureDrop

Canvas.DropObject:

If obj.PictureAvailable Then
  Me.Backdrop = obj.Picture
End If

ListBox.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("????")

ListBox.AcceptTextDrop

AcceptTextDrop

Permits text to be dropped on the control.

This line in the Open event of a control that can accept dragged text.

Me.AcceptTextDrop

ListBox.AddAllRows

AddAllRows(items() As String)

Creates a new row for every value in the items array.


ListBox.AddExpandableRow

AddExpandableRow(text As String)

Appends text in a new row to the end of the list and adds disclosure triangle only if the AllowExpandableRows property is set to True.

For multi-column ListBoxes, Item is always assigned to column zero. In the case of hierarchical ListBoxes, AddExpandableRow appends Item to the subitems of the expanded row when called in the ExpandRow event.

The following example adds creates a hierarchical ListBox. Note that AddExpandableRow must be called to create the hierarchical relationship.

Var s1, sub1 As String
Me.ColumnWidths = "150,0"
s1 = "Michigan,Ohio,Minnesota"
sub1 = "Grand Blanc,Bad Axe,Flint,Benton Harbor,"_
+ "Detroit;Cleveland,Columbus,Akron,Pleasantville;St. Paul,Frostbite Falls"
For i As Integer = 1 To s1.Split(",").Count
  If NthField(sub1, ";", i) <> "" Then
    Me.AddExpandableRow("")
    Me.CellValueAt(i - 1, 1) = NthField(sub1, ";", i)
  End If
  Me.CellValueAt(i - 1, 0) = NthField(s1, ",", i)
Next
Me.ColumnCount = 1

ListBox.AddExpandableRowAt

AddExpandableRowAt(index As Integer, text As String)

Creates a new expandable row at row (zero-based), moving the existing rows down. The text is always assigned to column zero. The optional parameter indent specifies the amount of indentation of the row in a ListBox where AllowExpandableRows (sometimes called a hierarchical ListBox) is True. The default is zero. It has no effect on a ListBoxe where AllowExpandableRows is False.

The following example in a PushButton adds a row to the ListBox with expandable rows that is used for the example in AddExpandableRow. It adds a new state to the list of cities and states.

Listbox1.AddExpandableRowAt(1, "New Hampshire")

ListBox.AddRow

AddRow(ParamArray Item As String)

Appends a new blank row to the end of the list.

Adding the string "October" to a new row in a ListBox named Listbox1:

ListBox1.AddRow("October")

The following line adds a row of months to a ListBox that has four columns:

Listbox1.AddRow("Sept", "Oct", "Nov", "Dec")

The following line adds a row of months to a ListBox that has four columns using an array:

Var months() As String = Array("Sept", "Oct", "Nov", "Dec")
ListBox1.AddRow(months)

The following adds a blank row then sets values for column 3:

ListBox1.AddRow
ListBox1.CellValueAt(ListBox1.LastAddedRowIndex, 2) = "Col 3"

ListBox.AddRowAt

AddRowAt(RowNumber As Integer, Item As String, [Indent As Integer])

Creates a new row at row (zero-based), moving the existing rows below row down. For multicolumn ListBoxes, text is always assigned to column zero. The optional parameter indent specifies the amount of indentation of the row in hierarchical ListBoxes. The default is zero. It has no effect on non-hierarchical ListBoxes.

The following example inserts a row in the ListBox. The code is in a PushButton.

Listbox1.AddRowAt(1, "Steven")

ListBox.CellBold

CellBold(RowNumber As Integer, ColumnNumber As Integer) As Boolean

Used to add or remove the bold style from the text of the specified cell. Note that row and column are zero-based.

Assign True to add the bold style and False to remove the bold style. For example:

ListBox1.CellBold(1, 1) = True

ListBox.CellCheckBoxStateAt

CellCheckBoxStateAt(Row As Integer, Column As Integer) As CheckBox

Used to get or set the state of the cell with the coordinates of row, column (zero-based). This assumes that the passed cell is a CheckBox cell. Use the CellType property to set a cell to a CheckBox cell. CheckBox is an Enum of the CheckBox class.

The CellCheckBoxStateAt method enables you to get or set the value of a tri-state Checkbox cell. Any cell of type TypeCheckbox box can store one of three values: Checked, Unchecked, and Indeterminate.

To set up a cell as TypeCheckbox, use code such as this in the Open event:

Me.CellTypeAt(1, 0) = ListBox.CellTypes.CheckBox

To change the state of the cell, use the VisualStates enum of the CheckBox control:

ListBox1.CellCheckBoxStateAt(1, 0) = Checkbox.VisualStates.Indeterminate

ListBox.CellItalic

CellItalic(RowNumber As Integer, ColumnNumber As Integer) As Boolean

Used to add or remove the italic style from the text of the specified cell. row and column are zero-based.

This example assigns True to apply the italic style.

ListBox1.CellItalic(1, 1) = True

ListBox.CellTagAt

CellTagAt(Row As Integer, Column As Integer) As Variant

Gets or sets a "hidden" identifier associated with the cell identified by its parameters. Row and Column are zero-based.

This example sets a tag for a cell.

Me.CellTagAt(1, 4) = "My Cell Tag"

This example displays the tag for a cell:

MessageBox(Me.CellTagAt(1, 4))

ListBox.CellToolTipAt

CellToolTipAt(RowNumber As Integer, ColumnNumber As Integer) As String

Used to set or get the help tag (i.e. tooltip) for a ListBox cell. row and column are zero-based.

The following adds a tip to cell 0,0. The tip is visible when the user moves the pointer over the cell.

Listbox1.CellToolTipAt(0, 0) = "Enter your full name."

ListBox.CellUnderline

CellUnderline(RowNumber As Integer, ColumnNumber As Integer) As Boolean

Used to add or remove the underline style from the text of the specified cell. row and column are zero-based.

Assign True to add the underline style and False to remove the underline style. For example:

ListBox1.CellUnderline(1, 1) = True

ListBox.CellValueAt

CellValueAt

Used to set the text of the cell based on the row and column numbers passed.

row and column are zero-based. The top-left cell is 0,0. The class constants AllColumns and AllRows can be used to specify that you wish to get or set all the values columns or rows. For example, the following specifies all columns in the last row added using AddRow or AddRowAt:

Me.CellValueAt(Me.LastAddedRowIndex, ListBox.AllColumns)

If you set this equal to a tab-delimited string, you can update the row with one line of code.

This example copies all cells from one ListBox into another:

ListBox2.CellValueAt(ListBox.AllRows, ListBox.AllColumns) = ListBox1.CellValueAt(ListBox.AllRows, ListBox.AllColumns)

The destination ListBox will have the same number of rows and columns as the source. Headers, CellTags, RowTags and ColumnTags are not copied.

In this example, the following code populates a two-column ListBox with the names of the controls in the window and their indexes.

Var i As Integer
For i = 0 To Self.ControlCount - 1 ' number of controls in window
  ListBox1.AddRow(Str(i)) ' first column
  ListBox1.CellValueAt(Listbox1.LastAddedRowIndex, 1) = Control(i).Name ' second column
Next

ListBox.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

ListBox.ColumnFromXY

ColumnFromXY(X As Integer, Y As Integer) As Integer

Returns the column index from the passed mouse x, y pixel coordinates.

The parameters X and Y are relative to the top, left corner of the ListBox. If you use System or System to get the mouse coordinates to use with this method, you'll need to take into account that those System values are relative to the top-left corner of the entire screen.

This code in the DoubleClick event of a ListBox obtains the indexes of the cell that was double-clicked:

Var xValue As Integer
xValue = System.MouseX - Me.Left - Self.Left ' Calculate current mouse position relative to top left of ListBox

Var yValue As Integer
yValue = System.MouseY - Me.Top - Self.Top ' Calculate current mouse position relative to top of ListBox.

Var row, column As Integer
row = Me.RowFromXY(xValue, yValue)
column=Me.ColumnFromXY(xValue, yValue)

MessageBox("You double-clicked in cell " + row.ToString + ", " + column.ToString)

If you use the ListBox on a ContainerControl, then you need to also take into account the Container size:

Var xValue As Integer
xValue = System.MouseX - Me.Left - Self.Left - Me.TrueWindow.Left ' Calculate current mouse position relative to top left of ListBox

Var yValue As Integer
yValue = System.MouseY - Me.Top - Self.Top - Me.TrueWindow.Top ' Calculate current mouse position relative to top of ListBox.

Var row, column As Integer
row = Me.RowFromXY(xValue, yValue)
column=Me.ColumnFromXY(xValue, yValue)

MessageBox("You double-clicked in cell " + row.ToString + ", " + column.ToString)

ListBox.ColumnSortTypeAt

ColumnSortTypeAt(Column As Integer) As ListBox

{

The default is Sortable. Sortable means that the column can be clicked on and will display mouse over events. If the column is NotSortable, then the header cannot be clicked on and will not display mouse over events. Setting Column to ListBox.AllColumns affects the header type of all columns.

The following code in the Open event of the ListBox sets the first two columns as sortable and the third column as non-sortable.

Me.ColumnSortTypeAt(0) = ListBox.SortTypes.Sortable
Me.ColumnSortTypeAt(1) = ListBox.SortTypes.Sortable
Me.ColumnSortTypeAt(2) = ListBox.SortTypes.NotSortable

ListBox.ColumnTagAt

ColumnTagAt(Column As Integer) As Variant

Gets and sets the ColumnTag for each column. Column is zero-based. ColumnTagAt can be viewed in the Debugger.

Me.ColumnTagAt(4) = "Enter your birthdate."

ListBox.DrawInto

DrawInto(g As Graphics, x As Integer, y As Integer)

Draws the contents of the RectControl into the specified Graphics context. The parameters x and y are the coordinates of the top, left corner.

This method does not work with HTMLViewer and OpenGLSurface.

This example draws the current control into the Graphics of a Picture and then displays it as the Backdrop of a Canvas:

Var p As New Picture(Me.Width, Me.Height)
Me.DrawInto(p.Graphics, 0, 0)
Canvas1.Backdrop = p

ListBox.EditCellAt

EditCellAt(Row As Integer, Column As Integer)

Scrolls the row, column cell into view (if necessary) and temporarily makes the cell editable. row and column are zero-based. It sets the focus within the ListBox to the row, column cell and selects its contents, if any. The editable cell has a focus ring around it.

Use the CellTypeAt or ColumnTypeAt properties to change a cell or column to “inline editable” when you want the user to be able to edit the contents of the ListBox. Then call the EditCellAt method for each cell. This gives the editable cell the focus and selects the current text of the cell, if any. Typing replaces the cell's contents. When the user presses Tab or Return or clicks in another cell, the cell loses the focus and the contents of the cell are saved (this also calls the CellAction event handler).

When a cell is editable, the ActiveTextControl property is the TextEdit that contains the contents of that cell. This may be a TextField or a TextArea depending on the specified column type. You can use this property to set or get the text of the ListBox cell, set the selection, or change other properties of the ListBox's TextField or TextArea.

The following code in the CellClick event makes the cell the user pressed on editable. The parameters row and column are passed to the function.

Me.CellTypeAt(row, column) = Listbox.CellTypes.TextField
Me.EditCellAt(row, column)

This code marks an entire column as editable:

ListBox1.ColumnTypeAt(3) = ListBox.CellTypes.TextArea

In the CellClick event handler, you can then check if the column was pressed and then enable editing:

If column = 3 Then
  Me.EditCellAt(row, column)
End If

ListBox.ExpandableRowAt

ExpandableRowAt(row As Integer) As Boolean

For hierarchical ListBoxes, is used to get or set whether the row should be displayed as expandable.

Me.AddExpandableRow("Players")
Me.ExpandableRowAt(Me.LastAddedRowIndex) = False ' Disable expandable indicator

ListBox.HeaderAt

HeaderAt As String

Returns the header for the column whose index is passed.

If you assign values to both HeaderAt and InitialValue, the first row of InitialValue is interpreted as the first row of data; otherwise, it is used as the header and the second row of InitialValue is used as the first row of data.

You can set the headers in a multi-column ListBox by assigning to HeaderAt(ListBox.AllColumns) the text of the headings separated by the tab character, e.g.,

Me.HeaderAt(ListBox.AllColumns) = "FirstName" + Chr(9) + "LastName"

You must use a space if you want an empty header; empty strings will use the default header.

ListBox1.HeaderAt(ListBox.AllColumns) = "" ' sets all headers of ListBox1 to their defaults.
ListBox1.HeaderAt(5) = "" ' sets column 5's header to its default heading
ListBox1.HeaderAt(5) = " " ' sets column 5's header to empty.

This example populates a three-column ListBox with headers:

ListBox1.HasHeader = True
ListBox1.HeaderAt(0) = "ID"
ListBox1.HeaderAt(1) = "JobTitle"
ListBox1.HeaderAt(2) = "Name"

ListBox.Invalidate

Invalidate([EraseBackground As Boolean])

Similar to RefreshRect, but causes the specified region of the RectControl to be marked dirty and to be redrawn when the window contents need to be redrawn. The region to be redrawn is specified by the X, Y, Width, and Height parameters. This form of Invalidate was formerly called InvalidateRect.

The following code refreshes the control. EraseBackground defaults to True.

Me.Invalidate(False)

ListBox.InvalidateCell

InvalidateCell(Row As Integer, Column As Integer)

Redraws the specified cell "from scratch" rather than using the data in the internal buffer.

row and column are zero-based. If you pass a -1 as the row or column parameter, it will redraw the specified entire row or column, i.e., Invalidate(2, -1) redraws row number 2. The CellBackgroundPaint and CellTextPaint events execute when InvalidateCell is called.

InvalidateCell should be necessary only if you are using a custom storage mechanism for your ListBox data. If the contents of the ListBox are stored in the ListBox cells, the ListBox will update automatically as needed.

This method doesn't have a high overhead if used unnecessarily since nothing will happen if the specified cell is not visible.

The following example redraws the specified cell.

Listbox1.InvalidateCell(1, 0)

ListBox.PressHeader

PressHeader(Column As Integer)

Causes the specified ListBox header to be pressed at column v (zero-based), causing a HeaderPressed event to occur. Calling this method does not update the sort direction.

This example presses the first column.

Listbox1.PressHeader(0)

ListBox.Refresh

Refresh(eraseBackground As Boolean)

Repaints the portion specified of the contents of the control immediately.

Calling this frequently can cause the code executing to slow down. It is often preferable to call RectControl instead.

Refresh the entire area:

Me.Refresh(False)

Refresh a portion of the area:

Me.Refresh(100, 150, 200, 300)

ListBox.RemoveAllRows

RemoveAllRows

Removes all rows in the ListBox, including any initial values that were specified in the IDE.

This example removes all the rows in ListBox1.

Listbox1.RemoveAllRows

ListBox.RemoveRowAt

RemoveRowAt(RowNumber As Integer)

Removes the specified row at index (zero-based).

This example removes the second row.

Listbox1.RemoveRowAt(1)

ListBox.RowDepthAt

RowDepthAt(row As Integer) As Integer

For hierarchical ListBoxes, this is the depth of the specified row in the hierarchy. A top-level row has RowDepth = 0.

Get depth of selected row:

Var row As Integer = ListBox1.RowCount
Var depth As Integer = ListBox1.RowDepthAt(row)

ListBox.RowExpandedAt

RowExpandedAt(RowNumber As Integer) As Boolean

Used to get or set the expanded state of the row passed.

The row must have been added with the AddExpandableRow method.

This example expands the first row of ListBox1 (if it is collapsed) or collapses it (if it was expanded). The row must have been added with the AddExpandableRow method:

ListBox1.RowExpandedAt(1) = Not ListBox1.RowExpandedAt(1)

ListBox.RowFromXY

RowFromXY(X As Integer, Y As Integer) As Integer

Returns the row index from the passed mouse x, y pixel coordinates.

The parameters X and Y are relative to the top, left corner of the ListBox. If you use System or System to get the mouse coordinates to use with this method, you'll need to take into account that those System values are relative to the top-left corner of the entire screen.

This code in the DoubleClick event of a ListBox added to a Window obtains the indexes of the cell that was double-clicked:

Var xValue As Integer
xValue = System.MouseX - Me.Left - Self.Left ' Calculate current mouse position relative to top left of ListBox

Var yValue As Integer
yValue = System.MouseY - Me.Top - Self.Top ' Calculate current mouse position relative to top of ListBox.

Var row, column As Integer
row = Me.RowFromXY(xValue, yValue)
column=Me.ColumnFromXY(xValue, yValue)

MessageBox("You double-clicked in cell " + row.ToString + ", " + column.ToString)

If the ListBox code is not on the window (perhaps it is in a subclass or ContainerControl), then you need to be sure to calculate the correct offsets. This code would be used for a ListBox on a ContainerControl:

Var xValue As Integer
xValue = System.MouseX - Me.Left - Self.Left - Me.TrueWindow.Left ' Calculate current mouse position relative to top left of ListBox

Var yValue As Integer
yValue = System.MouseY - Me.Top - Self.Top - Me.TrueWindow.Top ' Calculate current mouse position relative to top of ListBox.

Var row, column As Integer
row = Me.RowFromXY(xValue, yValue)
column=Me.ColumnFromXY(xValue, yValue)

MessageBox("You double-clicked in cell " + row.ToString + ", " + column.ToString)

ListBox.RowImageAt

RowImageAt(RowNumber As Integer) As Picture

Adds the image/picture assigned to the passed row index (zero-based).

The ListBox row does not resize to accommodate the Picture. If your picture does not fit via RowImageAt, use CellTextPaint or CellBackgroundPaint to draw the picture yourself.

The following example draws a picture in the first cell. The picture has been added to the project.

Listbox1.RowImageAt(0) = UserPhotoImage

ListBox.Rows

Rows As ListBoxRow

Allows you to iterate through all the rows in a ListBox.

In this example, the Tag of each row is examined and if it's found to be "Taxable", the ComputeTaxes method is called and passed the value of the row.

For Each row As ListBoxRow In ListBox1.Rows
  If row.Tag = "Taxable" then ComputeTaxes(row.ColumnValueAt(0))
Next

ListBox.RowTagAt

RowTagAt(Row As Integer) As Variant

Gets and sets the RowTag for the row (zero-based).

To set the tag:

ListBox1.RowTagAt(row) = "MyTag"

To get the tag:

myTag = ListBox1.RowTagAt(row)

ListBox.SetFocus

SetFocus

If applicable, sets the focus to the RectControl. 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 Window 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.

On the Mac 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 sets the focus to TextField1. If another control has the focus when this line is executed, then the user sees that TextField1 gets the focus.

TextField1.SetFocus

ListBox.Sort

Sort

Sorts the rows based on the current values of the SortingColumn and ColumnSortDirectionAt properties.

When AllowExpandableRows is True and a ListBox is sorted, the rows are sorted at all levels of the hierarchy, not just the base level.

To ensure the sort indicator displays after sorting you can force the header to refresh like this:

Listbox1.HasHeader = True

The following code sorts a ListBox in descending order on the first column.

' first column, descending order
ListBox1.ColumnSortDirectionAt(0) = ListBox.SortDirections.Descending
ListBox1.SortingColumn = 0 ' first column is the sort column
ListBox1.Sort

Event descriptions


ListBox.CellAction

CellAction(Row As Integer, Column As Integer)

If a cell is editable, a CellAction event occurs when the user finishes editing a cell. Row and Column are zero-based.

“Finishing editing” is defined as exiting the cell after clicking in it. Tabbing out of the editable cell or clicking another cell triggers this event. Clicking a checkbox in a checkbox cell also qualifies as "finishing editing".

The user doesn't necessarily have to change the contents.

This code will display changes made to an editable cell when the user finishes editing (by either pressing return or switching to a different cell):

If column = 2 Then ' Is this the editable column?
  MessageBox("You entered: " + Me.Cell(row, column))
End If

This event handler is also called when the user clicks a CheckBox cell:

If column = 3 Then ' Is this the CheckBox column?
  If Me.CellCheckBoxAt(row, column) Then
    MessageBox("You checked the checkbox in row " + row.ToString)
  Else
    MessageBox("You unchecked the checkbox in row " + row.ToString)
  End If
End If

ListBox.CellBackgroundPaint

CellBackgroundPaint(g As Graphics, Row As Integer, Column As Integer) As Boolean

The parameter g is a Graphics object that corresponds to the content area of the cell identified by the parameters Row, Column. 0,0 is the upper left of the cell. Returns a Boolean. True means the user has handled the background paint and no other processing is to be done with the background. In this case the user is responsible for all highlighting. False means the user wants the default background; this will overwrite your drawing on the row that needs to be highlighted as the row or column will be highlighted as appropriate (according to the platform and the hierarchical style).

This code can be used to do alternate row highlighting:

If row Mod 2 = 0 Then
  g.DrawingColor = &cf3f6fA
  g.FillRectangle(0, 0, g.Width, g.Height)
End If

This example paints the cell background red if the CellTag contains the string "Red":

If Me.CellTagAt(row, column ) = "Red" Then
  g.DrawingColor =Color.RGB(255, 0, 0)
  g.FillRectangle(0, 0, g.Width, g.Height)
End If

ListBox.CellClick

CellClick(Row As Integer, Column As Integer, X As Integer, Y As Integer) As Boolean

The user has clicked on the Row, Column cell. Row and Column are zero-based. The parameters X and Y are the x and y coordinates of the mouse click relative to the top-left corner of the cell that was clicked. X and Y are on the same scale of reference as the coordinates used by the Graphics property of the CellBackgroundPaint event.

To give the user the ability to edit the cell, change the CellType to Editable (ListBox.TypeEditable) and then call the EditCell method. The user will then get a focusing ring around the cell and the current text will become editable. When the user tabs out of the cell, the changes will be saved. You will get the CellAction event.

CellClick returns a Boolean. Returning True means that the event will not be processed further (i.e., editable cells won't be editable and ListBox selection won't change).

This code makes a cell editable when it is clicked:

If column = 2 Then ' Is this the editable column?
  Me.ColumnTypeAt(column) = ListBox.CellTypes.TextField
  Me.CellEditTextAt(row, column)

  Return True
End If

ListBox.CellGotFocus

CellGotFocus(Row As Integer, Column As Integer)

The user has selected an editable cell of a ListBox. Row and Column are zero-based. The Row and Column parameters indicate which cell just got the focus.


ListBox.CellKeyDown

CellKeyDown(Row As Integer, Column As Integer, Key As String) As Boolean

The user has pressed a key while a cell in the ListBox is being edited. Row and Column are zero-based.

This cell is identified by the Row and Column parameters. Key is the key that the user pressed.

CellKeyDown returns a Boolean. Returning True prevents the text from changing automatically and prevents the CellTextChange event from firing.


ListBox.CellLostFocus

CellLostFocus(Row As Integer, Column As Integer)

The Row, Column cell has just lost the focus. Row and Column are zero-based. The user could have clicked on another cell or pressed Tab, Return, or Escape.


ListBox.CellTextChange

CellTextChange(Row As Integer, Column As Integer)

Occurs after the KeyDown event if the KeyDown event returns False.

The event is passed the Row and Column of the cell being edited.


ListBox.CellTextPaint

CellTextPaint(g As Graphics, Row As Integer, Column As Integer, x As Integer, y As Integer) As Boolean

The parameter g is a Graphics object that corresponds to the text drawing area of the cell identified by Row, Column. Row and Column are zero-based. This does not necessarily correspond to the entire cell content area, for example, if you use a row picture in the cell.

In order for this event handler to be called, the cell itself must have been given a value, even if it is blank.

The parameters x and y are the coordinates of the suggested ideal location to draw text based on the current value of ColumnAlignment or CellAlignment, as well as the cell's font, font size, and font style.

The drawing order of the cell is as follows, with the background first:

  • Background

*Disclosure Triangle/Treebox *Checkbox *RowPicture *Text *Border

Although the border is painted last, it isn't advisable to change the state of the border in the CellTextPaint event since the area is determined by the size of the border before the cell is painted. It could leave unpainted areas or possibly cover up some of the painting you have done.

Returning True means the user has handled the text paint and no other processing is to be done with the text. In this case, the user is responsible for text highlighting. Text highlighting is currently only done for the hierarchical ListBox style. Returning False means the user wants the default text drawing. In this case, the text will be highlighted as appropriate (according to platform) for you automatically.

This code draws a small triangle on the right side of the cell (the code is using column 3 as the cell to draw into):

  Select Case column
  Case 3 ' Is this the column to draw into?
    ' Draw an arrow to indicate that clicking this field will
    ' display a menu
    g.DrawingColor = &c000000

    ' Points for a triangle on the right side of the cell
    Var points(6) As Integer
    points(1) = g.Width - 10
    points(2) = 1
    points(3) = g.Width
    points(4) = 1
    points(5) = g.Width - 5
    points(6) = 10

    g.FillPolygon(points)

    Return True
End Select

Now you can display a menu when the user clicks in the cell by putting code in the MouseDown and MouseUp event handlers.

This goes in MouseDown to allow the MouseUp event handler to be called:

If Me.ColumnFromXY(x, y) = 3 Then
  Return True
End If

This code in MouseUp displays a simple menu:

' Display menu if clicked in PopupMenu column
Var row As Integer = Me.RowFromXY(x, y)
Var col As Integer = Me.ColumnFromXY(x, y)

If col = 3 Then
  Me.SelectedIndex = row
  Me.Selected(row) = True

  Var base As New MenuItem
  base.AddMenu(New MenuItem("Red"))
  base.AddMenu(New MenuItem("Green"))
  base.AddMenu(New MenuItem("Blue"))
  base.AddMenu(New MenuItem("Black"))
  base.AddMenu(New MenuItem("White"))

  Var selectedMenu As MenuItem
  selectedMenu = base.PopUp

  If selectedMenu <> Nil Then
    MessageBox("You changed the color to " + selectedMenu.Value + ".")
  End If
End If

ListBox.Change

Change

The Change event is called when the row selection is changed by the user or by code.

The Change event handler is called when the row selection changes, not when cell contents change.

The Change event handler is called in response to the following user actions: * When the ListBox is clicked to give it the focus * When an empty row in the ListBox is clicked * When a cell is clicked even if it already is selected and the column is not editable * When a row is clicked to change the selection

If a column is editable, clicking in a cell calls the Change event but a second click to get an insertion point does not. Clicking on a header or a checkbox does not call the Change event.

Also, a programmatic change to ListBox also triggers the Change event.


ListBox.Close

Close

The control is about to close.


ListBox.CollapseRow

CollapseRow(Row As Integer)

The user has clicked on the disclosure triangle of the expanded Row passed or the rows expanded property was set false programmatically. Row is zero-based.


ListBox.CompareRows

CompareRows(Row1 As Integer, Row2 As Integer, Column As Integer, ByRef Result As Integer) As Boolean

The CompareRows event is used for sorting a column of a ListBox in a manner that is not provided by the default mechanism. Row and Column are zero-based. The result of the comparison is returned in the last parameter, Result, which is declared Byref. The default mechanism sorts cell values lexicographically. If you implement the event, it gets called during a ListBox sort, e.g., when a user clicks in the header area.

Parameters: * Row1: Row number of one of the rows being compared. * Row2: Row number of the other row being compared. * Column: Number of column being sorted.

Set Result to: * 0: If items in Row1 and Row2 in specified column are equal. * -1: Contents of Row1 < Contents of Row2. * 1: Contents of Row1 > Contents of Row2.

Return True if the returned Result parameter is accurate for sorting.

Return False if you want the ListBox to use the default lexicographic sorting of the column.

Suppose your ListBox contains a first column (numbered 0) which contains a string value. You can let the ListBox use the default lexicographic comparison for such a column. However, the second column (numbered 1) contains a numerical value that should be sorted as such. You can implement the RowCompared event as follows:

Function CompareRows(row1 As Integer, row2 As Integer, column As Integer, ByRef result As Integer) As Boolean
  Select Case column
  Case 0 ' This is a string column. Let the listbox manage it by returning false
    Return False

  Case 1 ' This is our numerical value column. Let's do the work ourselves
    If Val(Me.CellValueAt(row1, column )) < Val(Me.CellValueAt(row2, column)) Then
      result = -1
    ElseIf Val(Me.CellValueAt(row1, column)) > Val(Me.CellValueAt(row2, column)) Then
      result = 1
    Else
      result = 0
    End If
    Return True

  Else //some other column for which we let the listbox handle comparison
    Return False
  End Select
End Function

or, more simply, using the Sign function:

Function CompareRows(row1 As Integer, row2 As Integer, column As Integer, ByRef result As Integer) As Boolean
  Select Case column
  Case 0  ' This is a string column. Let the listbox manage it by returning false
    Return False

  Case 1 ' This is our numerical value column. Let's do the work ourselves
    result = Sign(Val(Me.CellValueAt(row1, column)) - Val(Me.CellValueAt( row2, column)))
    Return True

  Else //some other column for which we let the listbox handle comparison
    Return False
  End Select
End Function

To sort a column containing checkboxes use

Function CompareRows(row1 As Integer, row2 As Integer, column As Integer, ByRef result As Integer) As Boolean
  ' Column 0 contains checkboxes.
  ' We want to sort it by checkbox value, with unchecked rows before checked rows.

  Select Case column
  Case 0 ' column 0 contains our checkboxes
     If Me.CellCheckBoxValueAt(row1, column) XOr Me.CellCheckBoxValueAt(row2, column) Then
      ' CellCheckBox values are unequal.  If row1 is true, then row2 must be true and vice versa.
      If Me.CellCheckBoxValueAt(row1, column) Then
        ' row1 < row2
        result = 1
      Else
        ' row1 < row2
        result = -1
      End If
    Else
      ' CellCheckBox values are equal, so row1 = row2.
      result = 0
    End If
    Return True

  Else
    ' let the listbox do default comparison
    Return False
  End Select
End Function

ListBox.ConstructContextualMenu

ConstructContextualMenu(Base As MenuItem, x As Integer, y As Integer) As Boolean

This event is called when it is appropriate to display a contextual menu for the control.

This event handler is the recommended way to handle contextual menus because this event figures out whether the user has requested the contextual menu, regardless of how they did it. Depending on platform, it might be in the MouseUp or MouseDown event and it might be a right+click or by pressing the contextual menu key on the keyboard, for example.

Base is analogous to the menu bar for the contextual menu. Any items you add to Base will be shown as menu items. If you return False, the event is passed up the parent hierarchy.

If you return True, the contextual menu is displayed. The parameters x and y are the mouse locations. If the event was fired because of a non-mouse event, then x and y are both set to -1. See the example of a contextual menu in the following section.

The following ConstructContextualMenu event handler builds a menu with three menu items plus a submenu with three additional menu items.

' Add some items
base.AddMenu(New MenuItem("Test 1"))
base.AddMenu(New MenuItem("Test 2"))
base.AddMenu(New MenuItem("Test 3"))

' Add a Separator
base.AddMenu(New MenuItem(MenuItem.TextSeparator))

' Add a sub menu
Var submenu As New MenuItem("SubMenu")
submenu.AddMenu(New MenuItem("SubMenu Test 1"))
submenu.AddMenu(New MenuItem("SubMenu Test 2"))
submenu.AddMenu(New MenuItem("SubMenu Test 3"))
base.AddMenu(submenu)

' Add a Separator
base.AddMenu(New MenuItem(MenuItem.TextSeparator))

Return True

ListBox.ContextualMenuAction

ContextualMenuAction(HitItem As MenuItem) As Boolean

Fires when a contextual menuitem hitItem was selected but the Action event and the MenuHandler for the menuitem did not handle the menu selection.

This event gives you a chance to handle the menu selection by inspecting the menuitem's Text or Tag properties to see which item was selected. Use this in conjunction with ConstructContextualMenu if you have not specified the Action event or the Menu Handler for the items on the contextual menu. See the example of a contextual menu in the examples for the RectControl class.

Return True if this event has handled the item the user chose from the contextual menu. Returning False will cause the control's parent to execute its ContextualMenuAction event. This can be handy if you have the same contextual menu for several controls who share the same Parent (several on the same window for example). By returning False you can handle them all in a single event.

This simple event handler displays the value of the selected menu item.

If hitItem <> Nil Then MessageBox(hitItem.Value)
Return True

ListBox.DisclosureWidgetPaint

DisclosureWidgetPaint(g As Graphics, row As Integer, ByRef x As Integer, ByRef y As Integer, ByRef width As Integer, ByRef height As Integer)

Invoked for hierarchical ListBoxes when the framework needs to draw the disclosure triangle for a folder row. This is invoked after CellBackgroundPaint and before CellTextPaint.

The left, top, width and height parameters: * Default to the coordinates for drawing the built-in widget * These coordinates are also used for hit testing to determine if a mousedown should toggle the row's expanded state. * Are ByRef so the user can specify the location of the rectangle used for hit testing when drawing their own widget, if for instance the hit area is smaller than the drawn widget. * Setting width or height to zero will completely hide the triangle and no hit testing will be done. * Returning False causes the framework widget to be drawn. * Returning True prevents the framework from drawing its own disclosure widget, signaling that the event has performed all of the necessary drawing. * Changing the Width parameter and returning True will offset the graphic object that is provided in the following CellTextPaint event by the same offset. i.e. if the supplied Width is 10, but the code changes it to 5 the graphic object in the CellTextPaint event would be offset by 5 pixels to the left.


ListBox.DoubleClick

DoubleClick

The user has double-clicked on a row in the ListBox.


ListBox.DragEnter

DragEnter(obj As DragItem, Action As Integer) As Boolean

Fires when the passed DragItem enters the RectControl.

Returns a Boolean. Return True from this event to prevent the drop from occurring.

The Action parameter specifies the drag action. It can take the following class constants of the DragItem class:

Value

Class Constant

0

DragItem.DragActionDefault

1

DragItem.DragActionCopy

2

DragItem.DragActionMove

3

DragItem.DragActionLink

To restrict file drops to just folders (and not files), you can put this code in the DragEnter event:

If Not obj.FolderItem.IsFolder Then Return True

ListBox.DragExit

DragExit(obj As DragItem, Action As Integer)

Fires when the passed DragItem exits the RectControl.

The Obj parameter is the item being dragged. The Action parameter specifies the drag action. It can take the following class constants of the DragItem class:

Value

Constant

0

DragItem.DragActionDefault

1

DragItem.DragActionCopy

2

DragItem.DragActionMove

3

DragItem.DragActionLink


ListBox.DragOver

DragOver(x As Integer, y As Integer, obj As DragItem, Action As Integer) As Boolean

Fires when the DragItem is over the RectControl.

The Obj parameter is the object being dragged. The coordinates x and y are relative to the RectControl. Returns a Boolean. Return True from this event to prevent the drop from occurring.

The Action parameter specifies the drag action, which is typically done by holding down a modifier key (Shift, Alt, Option, Command, etc.) while doing the drag. It can take the following class constants of the DragItem class:

Value

Constant

0

DragItem.DragActionDefault

1

DragItem.DragActionCopy

2

DragItem.DragActionMove

3

DragItem.DragActionLink


ListBox.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 ListBox)

Invoked during dragging, similar to the DragOver event.

Event handlers can 'retarget' a drop by altering the row, parentRow, or location parameters.

  • x: The x coordinate of the drop, relative to the left of the ListBox.

  • y: The y coordinate of the drop, relative to the top of the ListBox.

  • obj: The data actually being dropped.

  • action: The drag action, which can be things like move or copy. Constants already exist in the DragItem class for this.

  • row: The proposed target row for the drop.

  • parentRow: When the ListBox is non-hierarchical, this will always be -1. When the ListBox is hierarchical, this is the row that the item is being dragged into. If the item is being dragged to the top level, parentRow will have a value of -1.

  • location: Whether the drop is going between two rows, on the row itself or just on the control. Uses the ListBox.DropLocations enum.

Returning True prevents the drop from occurring and the DragOver event from firing. Otherwise the DragOver event fires.


ListBox.DragReorderRows

DragReorderRows(NewPosition As Integer, ParentRow As Integer) As Boolean

This event is called when one or more rows are selected then moved in the ListBox to a new position. The ListBox property must be True in order for this event to be called.


ListBox.DragRow

DragRow(Drag As DragItem, Row As Integer) As Boolean

The user is dragging a row. Row is zero-based.

Drag is the DragItem object that is created automatically. Assign the values to the DragItem's properties that the user should drag. Row is the row of the ListBox that is being dragged. You must return True in this event handler to allow the drag to occur.

Setting up the DragRow event handler to allow the user to drag a value from a ListBox:

Function DragRow(drag As DragItem, row As Integer) As Boolean
  drag.Text = ListBox1.List(row)
  Return True
End Function

If you want to allow multiple row selection and dragging, then you need to process all the rows in the selection. This version of the DragRow event handler illustrates this.

Function DragRow(drag As DragItem, row As Integer) As Boolean
Dim nRows As Integer
Dim additionalItems As Boolean
For i As Integer = 0 To Me.RowCount - 1
  If Me.Selected(i) Then
    If Not additionalItems Then
      additionalItems = True
    Else
      drag.AddItem(0, 0, 0, 0) ' No need to specify a rect for just text
    End If
    drag.Text = Me.List(i)
  End If
Next

Return True
End Function

ListBox.DropObject

DropObject(Obj As DragItem Action As Integer)

The item represented by Obj has been dropped on the control.

The Obj parameter is the object being dragged. The Action parameter specifies the drag action. It can take the following class constants of the DragItem class:

{| class="genericTable" ! width=10% |Value ! width=60% |Class Constant |- |0 | DragItem.DragActionDefault |- |1 | DragItem.DragActionCopy |- |2 | DragItem.DragActionMove |- |3 | DragItem.DragActionLink |- |}

The following DropObject event handler can handle either a dropped picture or a dropped file. The type of file that it can handle needs to have been specified in a call to AcceptFileDrop prior to the drop, for example, in the Open event.

If Obj.PictureAvailable Then
  Me.Image = obj.Picture
ElseIf Obj.FolderItemAvailable Then
  Me.Image = Picture.Open(obj.FolderItem)
End If

ListBox.DropObjectOnRow

DropObjectOnRow(x As Integer, y As Integer, obj As DragItem, action As Integer, row As Integer, parentRow As Integer, location As ListBox)

Invoked when a drop has finished.

The row, parentRow, and location are the values previously set by the DragOverRow event handler.

The DropObject event fires after this event.

This code in the event handler shows the different values that can be passed for the Location parameter.

Select Case location
Case listbox.DropLocations.AfterAllRows
  MessageBox "add row after all rows"
Case listbox.DropLocations.AfterRow
  MessageBox "add row after rowindex = " + CStr(row)
Case listbox.DropLocations.OnControl
  MessageBox "drop occurred ON control"
Case listbox.DropLocations.OnRow
  MessageBox "add row to rowindex = " + CStr(row)
End Select

ListBox.EnableMenuItems

EnableMenuItems

The control has received the focus. Menu handlers are invoked if the control has the focus.


ListBox.ExpandRow

ExpandRow(Row As Integer)

The user has clicked on the disclosure triangle, or the expanded property was set to true programmatically, for a collapsed row that was added using AddFolder. Row is zero-based.

The rows are not persisted when the folder is later collapsed. Use the ExpandRow event handler to re-add rows as necessary.

This code adds children to the expanded row:

For childRow As Integer = 0 To 5
  Me.AddRow("Child " + Str(childRow) + " of row " + Me.CellValueAt(row, 0))
Next

ListBox.GotFocus

GotFocus

The ListBox has received the focus and has a selection rectangle around it.

Note

On Macintosh, controls other than text fields and lists will accept focus only if the full keyboard access option is enabled in System Preferences/Keyboard.


ListBox.HeaderBackgroundPaint

HeaderBackgroundPaint(g As Graphics, column As Integer)

Allow you to take control of drawing the background of the column headers.

Return True from this event to make any drawing you do in the Graphics parameter passed (g) take effect.


ListBox.HeaderContentPaint

HeaderContentPaint(g As Graphics, column As Integer)

Allow you to take control of drawing the content of the column headers.

Return True from this event to make any drawing you do in the Graphics parameter passed (g) take effect.


ListBox.HeaderPressed

HeaderPressed(Column As Integer) As Boolean

Runs after a ListBox header has been clicked/pressed. The index on Column is zero-based. You can use this event to specify whether you want to sort the column that was pressed. If you return True, the column is not sorted and it does not update the SortedColumn property.


ListBox.KeyDown

KeyDown(Key As String) As Boolean

The user has pressed the Key passed while the control has the focus.

How KeyDown works depends on the type of control.

TextField and TextArea Returning True means the key is intercepted, preventing the key from actually reaching the control at all. This would be useful if you want to override the behavior of the tab key for example. Returning False means the key reaches the control.

All Other Controls Returning True prevents the KeyDown event on the parent control (usually the window) from executing. Returning False results in the execution of the KeyDown event of the parent control.


ListBox.KeyUp

KeyUp(Key As String)

Fires when the passed Key is released in the RectControl that has the focus.

It is not guaranteed to be the same key that received the KeyDown event.


ListBox.LostFocus

LostFocus

The ListBox has lost the focus.

Note

On Macintosh, controls other than text fields and lists will accept and lose focus only if the full keyboard access option is enabled in System Preferences/Keyboard.


ListBox.MouseDown

MouseDown(x As Integer, y As Integer) As Boolean

The mouse button was pressed inside the control's region at the location passed in to x, y.

The coordinates x and y are local to the control, i.e. they represent the position of the mouse click relative to the upper-left corner or the ListBox.

Return True if you are going to handle the MouseDown. In such a case:

  • The Action event, if any, will not execute and the state of the object will not change.

  • You will receive the MouseDrag and MouseUp events.

If you return False, the system handles the MouseDown so the MouseDrag and MouseUp event handlers do not get called.

The MouseDown event uses the DragItem constructor when the user drags the contents of the control. It is:

Var d As DragItem
d = New DragItem(Self, Me.Left, Me.Top, Me.Width, Me.Height)
d.Picture = Me.Image
d.Drag ' Allow the drag

ListBox.MouseDrag

MouseDrag(x As Integer, y As Integer)

This event fires continuously after the mouse button was pressed inside the ListBox. Mouse location is local to the control passed in to x, y.

Note

This event will not occur unless you return True in the MouseDown event first.

The parameters x and y are local coordinates, i.e. they represent the position of the mouse relative to the upper-left corner of the ListBox.

As this event is fired continuously (hundreds of time per second), it is your responsibility to determine if the mouse has really moved.


ListBox.MouseEnter

MouseEnter

The mouse has entered the area of the control.


ListBox.MouseExit

MouseExit

The mouse has left the area of the control.


ListBox.MouseMove

MouseMove(X As Integer, Y As Integer)

The mouse has moved within the control to the coordinates passed. The coordinates are local to the control, not to the window.


ListBox.MouseUp

MouseUp(x As Integer, y As Integer)

The mouse button was released. Use the x and y parameters to determine if the mouse button was released within the control's boundaries.

Note

This event will not occur unless you return True in the MouseDown event. The return value is ignored.

The parameters x and y are local coordinates, i.e. they represent the position of the mouse click relative to the upper-left corner or the ListBox. Mouse clicks that are released to the left or above a control are negative.


ListBox.MouseWheel

MouseWheel(X As Integer, Y As Integer, DeltaX As Integer, DeltaY As Integer) As Boolean

The mouse wheel has been moved.

The parameters X and Y are the mouse coordinates relative to the control that has received the event. The parameters DeltaX and DeltaY hold the number of scroll lines the wheel has been moved horizontally and vertically, as defined by the operating system. DeltaX is positive when the user scrolls right and negative when scrolling to the left. DeltaY is positive when the user scrolls down and negative when scrolling up.

Returns a Boolean. Return True to prevent the event from propagating further.


ListBox.Open

Open

The control is about to be displayed. Use this event to initialize a control.

The Open event is called after the Constructor.

Be warned that initializing control property values using the Constructor instead of the Open event may result in those property values being overwritten by what is set in the Inspector. For best results, use the Open event for control initialization rather than the control Constructor.

If the control is supposed to handle drag and drop, you need to tell it which type of item it needs to be able to handle. The following example informs the control that pictures and files can be dropped on it. The type of the file it needs to support is specified via the File Types Editor.

Sub Open()
  Me.AcceptPictureDrop
  Me.AcceptFileDrop("JPEG")
End Sub

ListBox.SortColumn

SortColumn(Column As Integer) As Boolean

The user has clicked on the passed column header to sort that column or the Sort method was called. Column is zero-based.

Return True if you don't want the ListBox to be sorted.

Note that sorting is based on string comparisons. If you want to sort numbers, dates or CheckBoxes then you have to use a custom sort in the ListBox event.

If you're trying to prevent the user from sorting the column in the first place, use ListBox.

Notes

Items in single-column ListBoxes can be accessed using the List property. The List property is an array. Arrays are zero-based. This means that the first row of the List property of a ListBox is row number 0 (zero).


Iterating through rows

The Rows method returns a ListBoxRow which allows you to easily iterate through rows. In this example, the Tag of each row is examined and if it's found to be "Taxable", the ComputeTaxes method is called and passed the value of the row.

For Each row As ListboxRow In Listbox1.Rows
  If row.Tag = "Taxable" Then ComputeTaxes(row.Value)
Next

Configuring and accessing multiple columns

You can create multi-column ListBoxes by changing the ColumnCount property. The first column in a multi-column ListBox is column 0 (zero). This means that the ColumnCount property will always be one more than the number of the last column. The maximum number of columns is 256 (columns 0 through 255). You should set ColumnCount to the number of columns that you want to display. If you want to put data in an invisible column, set the column width to zero.

You can use the InitialValue property to set up the inital values of multi-column ListBoxes by separating the column values with tabs and row values with carriage returns.

The widths of columns in multi-column ListBoxes can be set by passing the widths as a list of values separated by commas to the ColumnWidths property. The widths can be passed in points or as percentages of the total width of the ListBox. If you don't pass widths for all the columns, the remaining columns will be evenly spaced over the remaining space. If too many widths are passed, the additional values are ignored. If the total of the widths passed is greater than the width of the ListBox, then the remaining columns will be truncated.

Specific cells in a multi-column ListBox can be accessed using the CellValueAt method. To populate a multi-column ListBox, first use the AddRow method to create the new row and populate the first column. Then use the CellValueAt method to add values to the other columns in the row. Use the LastAddedRowIndex property to get the index of the row you just added with AddRow.

For example, the following code populates a two-column ListBox with the names of the controls in the window and their indexes.

For i As Integer = 0 To Self.ControlCount - 1  ' number of controls in window
  ListBox1.AddRow(Str(i)) ' first column
  ListBox1.CellValueAt(Listbox1.LastAddedRowIndex, 1) = Control(i).Name ' second column
Next

Determining which cell was double-clicked

The DoubleClick event fires when the user double-clicks anywhere inside a ListBox, but the indexes of the cell that was double-clicked are not passed. You can determine which cell was double-clicked with the RowFromXY and ColumnFromXY methods. They use the x,y mouse coordinates where the double-click took place and translate them into the row and column indexes of the cell that was clicked. You need to adjust for the location of the ListBox on the screen relative to the top-left corner of the display.

This code in the MouseDown event obtains the indexes of the cell that was double-clicked.

Var row, column As Integer
row = Me.RowFromXY(x, y)
column = Me.ColumnFromXY(x, y)
MessageBox("You double-clicked in cell " + Str(row) + ", " + Str(column))

The parameters of RowFRomXY are relative to the top, left corner of the ListBox on a window. If you use the ListBox in a ContainerControl you have to take into account the distance of the container from the window edges.

Var row, column As Integer
row = Me.RowFromXY(System.MouseX - Me.Left - Self.Left - Me.TrueWindow.Left, System.MouseY - Me.Top - Self.Top - Me.TrueWindow.Top)
column = Me.ColumnFromXY(System.MouseX - Me.Left - Me.Parent.Left - Me.TrueWindow.Left, System.MouseY - Me.Top - Me.Parent.Top - Me.TrueWindow.Top)
MessageBox("You double-clicked in cell " + Str(row) + ", " + Str(column))

Making a cell editable

Use the CellTypeAt or ColumnTypeAt properties to change a cell or column to "inline editable" when you want the user to be able to edit the contents of the ListBox. Then call the EditCellAt method for each cell. This gives the focus to the editable cell and selects the current text of the cell, if any. Typing replaces the cell's contents. When the user presses Tab or Return or clicks in another cell, the cell loses the focus and the contents of the cell are saved.

The following code in the CellClick event makes the cell the user pressed on editable. The parameters row, and column are passed to the function.

Me.CellTypeAt(row, column) = ListBox.CellTypes.TextField
Me.EditCellAt(row, column)

When a cell is editable, the ActiveTextControl property is the TextField that contains the contents of that cell. You can use this property to set or get the text of the ListBox cell, set the selection, or change other properties of the ListBox's TextField.


Decimal alignment

When you use decimal alignment in a cell or column, you must take into account the fact that the decimal separator is aligned with the right edge of the column or cell. You must pass a negative number to CellAlignmentOffsetAt or ColumnAlignmentOffsetAt to make room for the numbers to the right of the decimal place. The correct value to pass depends on the number of digits to the right of the decimal place in the column or cell.


Resizing columns

There are two "modes" for column resizing. There is no formal mode property. Rather, the "mode" is implicitly set according to whether every column width is specified as an absolute amount. If you specify all columns either in points or as a percentage, you will be using the second mode. If you use an asterisk or leave a column width blank, you will be using the first mode.

  • A change to one column width affects the width of another column.

If column i gets bigger, column i+1 gets smaller by the same amount. This mode is great when using a ListBox without a horizontal scrollbar. You turn this mode on when you have at least one column width that is blank, or specified using an asterisk (e.g. "", " ", "*", or "4*").

Note: By design you can't resize the right edge of the last column in this mode. To resize the last column you need to resize the previous column.

  • Each column width is independent and can grow or shrink on its own.

You are responsible when the user does this, and you need to provide a horizontal scrollbar so that the user can get to the any headers that have been pushed out of view to the right. You enable this mode by making sure every column width is specified in terms of an absolute pixel width, or a percentage width (e.g. "20", or "35%"). If you use an asterisk or leave a column width blank, you will automatically be using the first mode.

You can switch between mode 1 and 2 at runtime using the same criteria as above.

The ColumnWidths property is equivalent to the concatenation of all of the ColumnWidthExpressions.

ColumnWidthExpressions are strings and they can represent several different types of column width calculations: absolute points (e.g., "45"), percentages (e.g. "22.3%"), and asterisk widths (or blanks), e.g. " ", "4*". The value "*" is equivalent to "1*" and can be used to mean "fill the remaining space."

ColumnWidthExpressions retain their type even when a column is resized. This means that if you:

  • Resize a window to which a ListBox is locked, it will grow or shrink. The columns grow or shrink as well if their expressions were -based (unless you use "0"), or percentage based (0%). If you want them to stay fixed, you need to express the ColumnWidthExpression as an absolute pixel value.

  • Resize a column by dragging it internally, it will recompute its percentage or asterisk value. This is so that you can, say, start with a two-column ListBox with no column widths specified (each column will take up half the space). Then drag one column to take up 3/4 of the space, then enlarge the ListBox, and now both column widths will enlarge so that their widths remain in a 3/4 to 1/4 ratio.

Changing the pixel value of a column will not change its fundamental type, but will change the value of that type.

Finally, if you want to create columns that won't get resized, change the UserResizable property for each of the columns in question. If you are using mode 1, you will need to change the UserResizable property for both the column and the one to its left.


Displaying data from a database

A ListBox is often used to display the results of database queries. A ListBox can be populated with the results of a query programmatically. See the example "Database Example" in the Examples folder.


Creating checkbox cells

The CellCheckBoxStateAt method enables you to get or set the value of a tri-state Checkbox cell. Any cell of type CheckBox can store one of three values: Checked, Unchecked, and Indeterminate.

To set up a cell as a Checkbox, use code such as this in the Open event:

Me.CellTypeAt(1, 0) = ListBox.CellTypes.CheckBox

To change the state of the cell, use the VisualStates enumeration of the CheckBox control:

ListBox1.CellCheckBoxStateAt(1, 0) = CheckBox.VisualStates.Indeterminate

The Indeterminate state places a minus sign in the checkbox (macOS) or fills in checkbox (Windows and Linux).


Customized scroll controls

Suppose you want a horizontal scroll bar that leaves room for a pop-up menu. In this example, a Scrollbar control has been added to the bottom area of the ListBox and a BevelButton control has been added to its right. The two controls take up the area that would be used by the built-in horizontal scrollbar.

The Scrollbar control has the following code in its Open event handler:

Me.Maximum = 50
Me.Minimum = 0
Me.LineStep = 5

The values for Maximum and LineStep were chosen to match the total width of the ListBox's columns. Adjust these values to suit your ListBox. Its ValueChanged event handler has the following line of code:

ListBox1.ScrollPositionX = Me.Value

In this way, the user can scroll the ListBox horizontally, bringing all columns into view.

The BevelButton enables the user to switch the ListBox between single-line selection and multiple-line selection. The BevelButton is set to have a normal menu and its Open event handler populates the menu with two items:

Me.AddRow("Single-line")
Me.AddRow("Multiple-line")

The BevelButton's Action event sets the value of the ListBox's SelectionType property:

Select Case Me.MenuValue
Case 0
  Listbox1.RowSelectionType = Listbox.RowSelectionTypes.Single
Case 1
  ListBox1.RowSelectionType = Listbox.RowSelectionTypes.Multiple
End Select

Adding horizontal and vertical grid lines

You can show horizontal and vertical rules for the entire ListBox using the GridLinesHorizontalStyle and GridLineVerticalStyle properties. You can also display horizontal and verticals rules for specific cells by using the CellBorderTopAt, CellBorderLeftAt, CellBorderRightAt, and CellBorderBottomAt properties.

The Default value of these properties is equivalent to "None". Other choices are: ThinDotted, ThinSolid, ThickSolid and DoubleThinSolid.


Displaying hierarchical rows

A hierarchical ListBox works like a tree view. Xojo uses the generic terms Expandable Rows to describe this style of ListBox. To allow for expandable rows, set the AllowExpandableRows property to true then rows can be expanded to display child content (and then collapsed later).

Windows uses plus and minus signs to indicate rows that are parents; macOS and Linux use disclosure triangles.

The following code, which is in the ListBox's Open event handler, populates a ListBox with expandable rows: The s1 string contains the parent level and sub1 contains the elements that are nested within each of s1's elements. It is a list of comma-delimited lists, with each list delimited by semicolons. The elements of sub1 are initially hidden because they are stored in a hidden column.

Var u As Integer
Var s1, sub1 As String
Me.ColumnWidths = "150,0"
s1 = "Michigan,Ohio,Minnesota"
sub1 = "Grand Blanc,Bad Axe,Flint,Benton Harbor,Detroit;Cleveland,Columbus,Akron,Pleasantville;St. Paul,Frostbite Falls"
u = CountFields(s1, ",")
For i As Integer =1 To u
  If NthField(sub1, ";", i) <> "" Then
    Me.AddExpandableRow("")
    Me.CellValueAt(i - 1, 1) = NthField(sub1, ";", i)
  End If
  Me.CellValueAt(i - 1, 0) = NthField(s1, ",", i)
Next
Me.ColumnCount = 1

Note that the AddExpandableRow method, rather than AddRow, is used to add the State names.

The following line of code in the DoubleClick event handler toggles the expanded state of the row that was double-clicked:

Me.RowExpandedAt(Me.SelectedRowIndex) = Not Me.RowExpandedAt(Me.SelectedRowIndex)

The following code in the ExpandRow event handler runs when the user double-clicks a collapsed element:

Var s1 As String
Var u As Integer
s1 = Me.CellValueAt(row, 1)
u = CountFields(s1, ",")
For i As Integer = 1 To u
  Me.AddRow("")
  Me.CellValueAt(Me.LastAddedRowIndex, 0) = NthField(s1, ",", i)
Next

It creates the sublist rows each time the user double-clicks a collapsed state name.

If the ListBox has the AllowExpandableRows property selected, then collapsing is handled automatically when the user collapses an item. If AllowExpandableRows is false, then you need code such as this in the CollapseRow event handler:

Var u, numSubRows As Integer
numSubRows = CountFields(Me.Cell(row, 1), ",")
u = row + 1
For i As Integer = row + numSubRows DownTo u
  Me.RemoveRowAt(i)
Next

It removes the rows that were created by the ExpandRow event handler.


Drag and drop

The following example allows the user to drag one row from ListBox1 to ListBox2. ListBox1 has its AllowRowDragging property set to True and its RowSelectionType property set to Single. Its DragRow event handler is as follows:

Function DragRow (drag As DragItem, row As Integer) As Boolean
  drag.Text = Me.List(row)
  Return True ' allow the drag
End Function

ListBox2's Open event handler has the line:

Me.AcceptTextDrop

Its DropObject event handler is this:

Sub DropObject(obj As DragItem)
  Me.AddRow(obj.Text) ' adds the dropped text as a new row
End Sub

Drag and drop multiple rows

The following code allows the user to drag more than one row from ListBox1 to ListBox2. The dragged rows are added to the end of the list.

ListBox1 has its AllowRowDragging property set to True, enabling items in its list to be dragged, and its RowSelectionType property set to Multiple. Its DragRow event handler is as follows:

Function DragRow (Drag As DragItem, Row As Integer) As Boolean
  Var nRows As Integer
  nRows = Me.ListCount - 1
  For i As Integer = 0 To nRows
    If Me.Selected(i) Then
      Drag.AddItem(0, 0, 20, 4)
      Drag.Text = Me.List(i) ' get text
    End If
  Next
  Return True ' allow the drag
End Function

It uses the AddItem method of the DragItem to add an additional item to the DragItem each selected row. The DropObject event handler then cycles through all items to retrieve all dragged rows.

ListBox2 has the following line of code in its Open event handler. It permits it to receive dragged text.

Me.AcceptTextDrop

Its DropObject event handler checks to see if the dragged object is text; if it is, it adds a row to the end of the list and assigns the text property of the dragged object to the new row: It loops through all items in the DragItem until NextItem returns False.

Sub DropObject(obj As DragItem)
  Do
    If obj.TextAvailable Then
      Me.AddRow(obj.Text)
    End If
  Loop Until Not obj.NextItem
End Sub

You can also drag from ListBox1 to the desktop to get a text clipping or to another application that supports text drag and drop.


Changing the background color of cells

This code, which is placed in the CellBackgroundPaint event, assigns alternating colors to the rows in a ListBox:

If row Mod 2 = 0 Then
  g.DrawingColor= &cD2FFF3
Else
  g.DrawingColor= &cD2EDF5
End If
g.FillRectangle(0, 0, g.Width, g.Height)

Notes: The CellBackgroundPaint event passes the parameters g (Graphics), and the row and column numbers (as Integer). You can assign a color to the DrawingColor property by creating it as a constant in the App class or a module and assign the color constant to the DrawingColor property. The following line in the CellTextPaint event draws the text in the preceding example in red:

g.DrawingColor =Color.RGB(255, 0, 0)

The CellTextPaint event is passed the coordinates of the suggested starting position to draw text in the parameters x and y. You can use them in a call to the DrawText method to specify the string to draw in a particular cell:

If row = 4 And column = 1 Then
  g.DrawingColor =Color.RGB(255, 0, 0)
  g.DrawText("Payment Overdue!", x, y)
End If
Return True

Sorting rows

To sort a ListBox, set the column on which the ListBox will be sorted with the SortingColumn property. Specify the sort direction on that column with the ColumnSortDirectionAt property, and then do the sort by calling the Sort method.

The following code sorts a ListBox in descending order on the first column.

' first column, descending order
ListBox1.ColumnsortDirectionAt(0) = ListBox.SortDirections.Descending
ListBox1.SortingColumn = 0 ' first column is the sort column
ListBox1.Sort

You can also sort a column based on the current value of ColumnSortDirectionAt by calling the PressHeader method. This method programmatically clicks the header for the column passed to it.

Note that sorting is based on string comparisons. If you want to sort numbers or CheckBoxes then you have to use a custom sort.


Sorting rows with your own algorithm

Use the CompareRows event handler to perform custom sorting on the displayed data. You will want to use custom sorting to property sort numerical data, which by default sorts as a string. This causes "2" to be greater than "100" because the values are treated as strings. You can also provide a custom sort for CheckBox columns, dates and any other information that you may want to sort differently than how it displays as a string.

The following example uses the CompareRows event to sort columns of numbers numerically:

Function CompareRows(row1 As Integer, row2 As Integer, column As Integer, ByRef result As Integer) As Boolean
  If Val(Me.CellValueAt(row1, column)) > Val(Me.CellValueAt(row2, column)) Then
    result = 1
  Else
    result = -1
  End If

  Return True ' Use the custom sort
End Function

With this code in place, the correct (numerical) sorting is done whenever the user clicks the header area. Test to be sure that the custom sort affects only the numerical columns.

To sort dates, store the SecondsFrom1970 (or SQLiteDate) property of the DateTime in the CellTagAt for the column and use it to sort instead of the displayed value.

Sample code

Adding a row to ListBox1:

ListBox1.AddRow("October")

Adding a row at row 1 in ListBox1:

ListBox1.AddRowAt(1, "October")

Creating a three-column ListBox and adding the headings and the first row of information:

ListBox1.ColumnCount = 3

ListBox1.HasHeader = True
ListBox1.HeaderAt(0) = "Name"
ListBox1.HeaderAt(1) = "Phone"
ListBox1.HeaderAt(2) = "Email"

ListBox1.AddRow("Milton")
ListBox1.CellValueAt(ListBox1.LastAddedRowIndex, 1) = "555-2212"
ListBox1.CellValueAt(ListBox1.LastAddedRowIndex, 2) = "milt@fredonia.com"

Changing all items in the ListBox to bold, underline:

ListBox1.Bold = True
ListBox1.Underline = True

Copying the fifth element of ListBox1 to another variable:

Var e As String
e = ListBox1.List(4)

Adding a column to ListBox1 and setting the widths of the columns to 50 and 65 points, respectively:

ListBox1.ColumnCount = 2
ListBox1.ColumnWidths = "50,65"

Setting the number of columns of ListBox1 to three and setting the widths of the columns to 60%, 20% and 20% respectively:

ListBox1.ColumnCount = 3
ListBox1.ColumnWidths = "60%,20%,20%"

If ListBox1 is 100 points wide and has three columns, the following code will set the columns widths as indicated but the last column will only be 10 points wide instead of 20:

ListBox1.ColumnWidths = "60,30,20"

If ListBox1 is 100 points wide and has three columns, the following code will set the columns widths but the last column will not be displayed:

ListBox1.ColumnWidths = "60,40,20"

Copying the fifth row of the third column of ListBox1 to another variable:

Var e As String
e = ListBox1.CellValueAt(4, 2)

Assigning a value to the fifth row of the third column of ListBox1:

ListBox1.CellValueAt(4, 2) = "Bill"

Setting the fifth row of the third column of ListBox1 to bold, italic:

ListBox1.CellBold(4, 2) = True
ListBox1.CellItalic(4, 2) = True

Adding a row with the text "Users" in the first cell and placing an image of a folder to the left of the text. The picture "usersFolder" has been added to the project.

ListBox1.AddRow("Users")
ListBox1.RowImageAt(0) = UsersFolder

Setting up the DragRow event handler to allow the user to drag a value from a ListBox:

Function DragRow(Drag As DragItem, Row As Integer) As Boolean
  Drag.Text = ListBox1.List(Row)
  Return True
End Function

Summing the numeric values of the selected rows:

Var total As Integer
For i As Integer = 0 To ListBox1.LastRowIndex
  If ListBox1.Selected(i) Then
    total = total + Val(ListBox1.List(i))
  End If
Next

This code expands the first row of ListBox1 (if it is collapsed) or collapses it (if it was expanded). The row must have been added with the AddFolder method:

ListBox1.ExpandedRowAt(1) = Not ListBox1.ExpandedRowAt(1)

This code populates a three-column ListBox with headings:

ListBox1.HasHeader = True
ListBox1.HeaderAt(0) = "ID"
ListBox1.HeaderAt(1) = "JobTitle"
ListBox1.HeaderAt(2) = "Name"

This code sets up a ListBox with four visible columns plus one hidden column. Column zero is hidden:

Me.ColumnCount = 5
Me.ColumnWidths = "0,25%,25%,25%,25%"
Me.HasHeader = True
Me.HeaderAt(0) = "ID"
Me.HeaderAt(1) = "FirstName"
Me.HeaderAt(2) = "LastName"
Me.HeaderAt(3) = "Phone"
Me.HeaderAt(4) = "Zip"

The following line of code displays the value of the hidden column in the selected row:

MessageBox(ListBox1.CellValueAt(ListBox1.SelectedRowIndex, 0))

Compatibility

All project types on all supported operating systems.

See also

RectControl parent class; TextField controls; DatabaseColumn, ListColumn, RowSet classes