Xdialog ListBoxes - Dynamically Computing the Display Expression

Description

A common requirement in an Xdialog is to display a listbox showing data from an array. The array is often a property array, and so the Xdialog displays data from one of the properties in the array. For example, the property array shown below has 'fname' and 'lname' properties, and the Xdialog shows the value in the 'lname' property:

dim arr[0] as p
i = arr.append();
arr[i].fname = "Sam"
arr[i].lname = "Raven"
i = arr.append();
arr[i].fname = "Charles"
arr[i].lname = "Chambliss"
i = arr.append();
arr[i].fname = "Dion"
arr[i].lname = "Smits"


ui_dlg_box("Show Lname",<<%dlg%
[.50,20index^#arr[[[\].lname];
%dlg%)

The resulting Xdialog looks like this:

But, what if you wanted the listbox to show both the 'fname' and 'lname' property? You could pre-process the array and add a new property called (say) 'Display' value to the array and then display that property in the array. But a better approach is to use the new option to dynamically calculate the display property of the listbox. This is done by using a special owner draw format. The owner draw format is =expression, where expression is some expression that you want to evaluate. The expression can reference a special variable called value that passes in a reference to the current row in the array. Here of some examples of owner draw formats:

  • In this example, propertyName is a variable that contains the name of the property (e.g. 'fname' or 'lname') that you want to display

    %O==eval(value+ "." + propertyName)%
  • In this example, the expression returns the 'fname' and 'lname' properties of the array.

    %O==eval(value+".fname+' '+" + value + ".lname" )
  • In this example, another UDF (testFN()) is called to compute the display value in the listbox.

    %O==testFNvalue?%

Here is an example that demonstrates the use of these format strings:

dim arr[0] as p
i = arr.append()
arr[i].fname = "Sam"
arr[i].lname = "Raven"
i = arr.append()
arr[i].fname = "Charles"
arr[i].lname = "Chambliss"
i = arr.append()
arr[i].fname = "Dion"
arr[i].lname = "Smits"

index = 1
dim fmt as c = ".fname"
ui_dlg_box("Owner Draw Listbox - Computed Display",<<%dlg%
{wrap=40}
{repaint_begin=fmt}
Select the property to display:;
[.10fmt^={.fname,.lname}];
[%O==eval(value+fmt)%.50,5index^#arr];
Listbox can show an expression showing a calculation involving properties in the array:;
[%O==eval(value+".fname+' '+" + value + ".lname" )%.50,5index^#arr];
A more complex expression:;
[%O==eval("upper(" + value+".fname)+' '+" + value + ".lname" )%.50,5index^#arr];
You can call a UDF to compute the data to display:;
\(This is the most flexible option.);
[%O==testFNvalue?%.50,5index^#arr];
{repaint_end}

%dlg%)

'value is a placeholder for 'arr'. eval(value) passes in the current row in the array to the function.


function testFN as c (ar as p)
testFN = upper(ar.lname) + ", " + f_upperar.fname?
if ar.lname = "chambliss" then 
testFN = "{I:'$$generic.orb.green.small'} " + testFN
else
testFN = "{I:'$$generic.orb.blue.small'} " + testFN
end if 

end function