Sign in Join
Wiki copytemporary

TListView: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11**TListView** ![](/wiki-images/d/d7/Tlistview.png) is a visible component on the [[Common Controls tab]] of the [[Component Palette]] that provides a list view of its associated Items. Items can be represented by an icon from each of the associated [[TImageList|TImageLists]]: SmallImages, LargeImages and StateImages.
22
33## Notes
44
55- **GetNextItem**() requires StartItem to be provided. This is incompatible with Delphi's GetNextItem(), where startItem is allowed to be **nil**, which will perform the search from the relative (direction driven) start.
66
77## Sorting
88
99`TODO: add description on how OwnerData affects the sorting`
1010
1111Sorting is (typically?) applied when using **vsReport** ViewStyle, as it's column driven (with Sortcolumn index required). Sorting might be a time consuming for a larger data scale (when comparison of items takes a considerable time).
1212
1313**SortType** is the key property in order to perform any sorting in TListView.
1414
1515
1616**stNone** - (the default value) that no sorting should be for the control.
1717
1818**stText** - the text of a cells would be used for item comparison. The actual text entry is controlled by **SortColumn** property. Note the default sorting comparison is actually treats the text as Ansi, rather than UTF8. Thus the result might be undesired for the non-English texts
1919
2020**stData** - the default sorting comparison treats **Data** property as an integer value (by casting pointer to an integer) and sorts the according to value. (in most cases such sorting is useless, unless "Data" is an actual integer casted to the pointer)
2121
2222**stBoth** - treated as **stText** for in the default sorting comparison.
2323
2424Unless using text sorting, the default comparison method is not the best approach, instead a custom comparison could be used. The custom comparison is assigned with **OnCompare** event of TListView. The following parameters are passed:
2525
2626
2727**Sender** - TListview that's being sorted
2828
2929**Item1** - one TListItem being compared
3030
3131**Item2** - another TListItem being compared to the one
3232
3333**Data** - is not used and is always passed as zero. (provided for Delphi compatibility)
3434
3535**Compare** - the result of the comparison, that must be populated by the event. The following values should be assigned to the **Compare** argument.
3636
3737
3838-1 - if Item1 should show up "earlier" in Ascending order, than Item2. (Item1 is less than Item2)
3939
40400 - if two items are equal
4141
42421 - if Item2 should show up "earlier" in Ascending order, than Item1. (Item2 is less than Item1)
4343
4444It's a normal practice to reverse the comparison result value, if SortDirection is descending. I.e.:
4545
4646```delphi
4747procedure TForm1.ListView1OnCompare(Sender: TObject; Item1, Item2: TListItem;
4848 Data: Integer; var Compare: Integer)
4949begin
5050 ... do the comparison...
5151
5252 if TListView(Sender).SortDirection = sdDescending then
5353 Compare := -Compare;
5454end;
5555```
5656
5757The OnCompare event should check for **SortType**, **SortColumn** and **SortDirection** properties of TListView, and do adjust the comparison result respectively of those properties.
5858
5959Method **Sort** performs of items, if **SortType** is other than **stNone** and SortColumn is assigned to a valid column index.
6060
6161Method **CustomSort** performs a one-time sorting using a provided sorting function.
6262
6363
6464ASortProc: TLVCompare - sorting function
6565
6666AOptionalParam: PtrInt - sorting parameter
6767
6868Sorting parameter is ignored (provided for the Delphi compatibility). If **ASortProc** is passed as nil, then the either sorting OnCompare is used or default sorting.
6969
7070Typically the sorting can be requested by a user. Whenever a user clicks on a column header, that requires to either sort (initially ascendancy) or to switch to the opposite sorting order (either from ascendant to descendant, or back). It's not a rule, but a common expectation. For some data sets selecting sorting might not make any sense. **AutoSort** (default value is true)the property of TListview controls, if the listview should be sorted automatically, as soon as user clicks on a column header. **AutoSort** will have no effect, while **SortType** is set to **stNone**.
7171
7272**AlphaSort** is a convenience method, that changes the settings to ascending sort (SortDirection=sdAscending) based on the text (SortType=stText) of the first column (SortColumn=0). Note that the actual properties are changed.
7373
7474### Sort Indicator
7575
7676Originating from: <https://bugs.freepascal.org/view.php?id=36281>
7777
7878In trunk since r62567
7979
80801\) Add a new property **SortIndicator** to TListViewColumn. The property controls system native sort indicator.
8181
8282The indicator is acting solely as a decorative feature. (Doesn't have any effect on the sorting). The indicator has 3 possible values
8383
8484
8585**siNone** - no sort indicator should be shown
8686
8787**siAscending** - ascending indicator should be shown
8888
8989**siDescending** - descending indicator should be shown
9090
9191The property can work independently of other TListview sorting properties.
9292
93-<figure>
94-<img src="autosort0.gif" title="autosort0.gif" />
95-<figcaption>autosort0.gif</figcaption>
96-</figure>
93+![](/wiki-images/2/29/Autosort0.gif)
9794
98952\) Add new property **AutoSortIndicator** to TListView. The property is intended to be used as a compliment to **AutoSort** property. If both are enabled, LCL code controls the current selection of the column sortindicator according to **AutoSort** rules.
9996
100-<figure>
101-<img src="autosort2.gif" title="autosort2.gif" />
102-<figcaption>autosort2.gif</figcaption>
103-</figure>
97+![](/wiki-images/7/78/Autosort2.gif)
10498
10599Early 2021 it was noticed that if you are using Qt5 and you have TListView.SortDirection set to sdAscending (the default), then setting a column's Sort Indicator to siDescending displays an ascending indicator. This does not happen with GTK2 or GTK3. Setting SortDirection to sdDescending makes all other combinations work fine so, seems an easy solution. Logged <https://bugs.freepascal.org/view.php?id=38393>
106100
107101## Custom drawing
108102
109103There is a good article on custom-drawing `TListView`: <https://delphidabbler.com/articles/article-16>. Most of the sample code in this article is working in Lazarus, too, however only **on Windows**. Here are some excerpts:
110104
111105Note: Keep the `OwnerDraw` property of the `TListView` at `false`.
112106
113107### Alternating row colors
114108
115109![](/wiki-images/7/70/Listview_alternating_rowcolors.png) Attach this handler for the `OnCustomDrawItem` event which is responsible for painting a full row. When the `DefaultDraw` parameter of the event handler is unchanged (i.e., `true`) then control still paints the text and additional gimmicks such as icons or checkboxes (see screenshot at the right):
116110
117111``` Pascal
118112procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
119113 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
120114begin
121115 if Odd(Item.Index) then
122116 // odd list items have green background
123117 ListView1.Canvas.Brush.Color := clMoneyGreen
124118 else
125119 // even list items have window colour background
126120 ListView1.Canvas.Brush.Color := clWindow;
127121end;
128122```
129123
130124### Individual column colors
131125
132126At first prepare a procedure to set the brush color for each ListView column:
133127
134128``` Pascal
135129{ Sets the brush colour for the column. Our ListView has 3 columns }
136130procedure TForm1.SetLVColumnColour(AColIndex: Integer);
137131const
138132 cRainbow: array[0..2] of TColor = ($FFCCCC, $CCFFCC, $CCCCFF);
139133begin
140134 ListView1.Canvas.Brush.Color := cRainBow[AColumnIndex];
141135end;
142136```
143137
144138Then provide a handler of the `OnCustomDrawItem` event which is responsible for painting of the entire row and, in particular, of the 1st column, and the `OnCustomDrawSubItem` event which is called when the other columns are painted: ![](/wiki-images/1/1d/Listview_different_column_colors.png)
145139
146140``` Pascal
147141{ Draw the "Caption" column }
148142procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
149143 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
150144begin
151145 SetLVColumnColour(0);
152146end;
153147
154148{ Draw the sub item columns }
155149procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
156150 Item: TListItem; SubItem: Integer; State: TCustomDrawState;
157151 var DefaultDraw: Boolean);
158152begin
159153 SetLVColumnColour(SubItem);
160154end;
161155```
162156
163157## Widgetset Implementation
164158
165159ListView is implemented via TWSCustomListViewClassinterface.
166160
167-<table>
168-<thead>
169-<tr>
170-<th><p>Method</p></th>
171-<th><p>Description</p></th>
172-</tr>
173-</thead>
174-<tbody>
175-<tr>
176-<td><p>SelectAll</p></td>
177-<td><p>The method provides a parameter <strong>AIsSet</strong>.</p>
178-<p>If the parameter is set to <strong>true</strong> then all items should selected in the view. If it's <strong>false</strong> then, all parameters should deselected.</p>
179-<p>It's important that the event shouldn't trigger any events, as LCL will call SelectChange event by itself.</p></td>
180-</tr>
181-</tbody>
182-</table>
161+**Method**
162+
163+**Description**
164+
165+SelectAll
166+
167+The method provides a parameter **AIsSet**.
168+
169+If the parameter is set to **true** then all items should selected in the view. If it's **false** then, all parameters should deselected.
170+
171+It's important that the event shouldn't trigger any events, as LCL will call SelectChange event by itself.
183172
184173## See also
185174
186175- [[doc:lcl/comctrls/tlistview.html|Doc. TListView]]
187176- [[TTreeView]]
188177- [[TShellListView]]
189178
190179---
191180*From the Free Pascal wiki, page "TListView", as it stood on 2023-04-28 after a change by Wp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history