Format ObjectListView

ListView display is very flexible. Here, we introduce only some approaches, some patterns. 

Variable Column Layout  

The ListView can change its column layout during runtime.  It is possible to change the number of columns and to rename them.

Columns are described via SetFormat statements. It makes sense to pool all column descriptions (formats) for each view. The command SetFormatName does this. To switch to another view, it is only necessary to change the format.

Example: A ListView shall display persons. The user shall be able to choose between two degrees of detail. The two formats are generated in two macros. The ObjectListView doesn't have a header, this will be set with the formats:

Define(SetFormatA)
  "A" SetFormatName(, LV)
  [ "CX_PERSON::name" HEADER T("Name", "Name") ] SetFormat(, LV)
  [ "CX_PERSON::comment" HEADER T("Kommentar", "Comment") ] SetFormat(, LV)
;

Define(SetFormatB)
  "B" SetFormatName(, LV)
  [ "CX_PERSON::name" HEADER T("Name", "Name") ] SetFormat(, LV)
  [ "CX_PERSON::firstName" HEADER T("Vorname", "First name") ] SetFormat(, LV)
  [ "CX_PERSON::comment" HEADER T("Kommentar", "Comment") ] SetFormat(, LV)
;

Format A has two columns, format B three. It would not make sense to display both formats at the same time, since the second column has a different meaning.

The following code switches the ListView header to the format A:

ResetWindow(, LV)
SetFormatA

This code switches a ListView with content to the format B:

ResetWindow(, LV)
SetFormatB
GetCollection(, LV) UpdateObox(, LV)

It is technically possible to introduce both formats at once to the ListView. It doesn't make sense though. Therefore, only one format should be set at the time (a format family; further down we can see an example with two formats, formats, that are displaying the same content). The command ResetWindow deletes all formats. 

Fixed Column Layout

The format for all columns is set once and doesn't need to be changed. This is the easiest way of formatting a ListView. The header can be set via header command, or - just like in the example - indicated directly in the SetFormat statement.

Reformat Single Lines

In case single lines shall be formatted differently, it is possible to define further formats for this. It will be switched to these formats before inserting into the ListView. It is important, that these formats display the same information, so ListView remains logically. The example from above is now developed a bit more: For some people, the name shall be displayed in red and the first name in blue:

Define(SetFormatB)
  "B.normal" SetFormatName(, LV)
  [ "CX_PERSON::name" HEADER T("Name", "Name") ] SetFormat(, LV)
  [ "CX_PERSON::firstName" HEADER T("Vorname", "First name") ] SetFormat(, LV)
  [ "CX_PERSON::comment" HEADER T("Kommentar", "Comment") ] SetFormat(, LV)
  "B.colored" SetFormatName(, LV)
  [ "CX_PERSON::name" HEADER T("Name", "Name") COLOR RED ] SetFormat(, LV)
  [ "CX_PERSON::firstName" HEADER T("Vorname", "First name") COLOR BLUE ] SetFormat(, LV)
  [ "CX_PERSON::comment" HEADER T("Kommentar", "Comment") ] SetFormat(, LV)
;

The format name clearly shows, that it belongs to the format family "B". Before inserting an object into the ListView, the required format needs to be set via SetFormatName.

Switching to format A is done as shown above. Going back to format B is not that easy, since each object needs to be assigned separately to the matching B-format. All persons with a comment shall be colored:

Var(persons) ...  // contains the objects
ResetWindow(, LV)
ClearObox(, LV)
SetFormatB
persons iterate {
  Dup Copy(comment) is(INVALID) if { "B.normal" SetFormatName(, LV) }
  else { "B.colored" SetFormatName(, LV) }
  FillObox(, LV)
}