Tuesday, March 31, 2026

More about dual list boxes

After a minimal amount of research, I discovered that the dual listbox is regarded as a very good solution when one wants to select and organise options. I did some work with CoPilot on the subject last night; most of the time went on creating an ancestral form for the dual listbox dialog and a small amount of time working on a form that inherits from the ancestor. This morning I spent some time improving the visual aspects of the form and fixing a few bugs that had crept in (mainly misnaming errors).

Above is pictured an example of the form when it is populated with data. Just to make things slightly more difficult, it is of course drawn right-to-left. Until now, if I was feeling adventurous, I would place a bevel around a listbox or grid, slightly improving the appearance, but it struck me that it would be better to use a coloured panel and place the listbox on top of the panel - that's what gives the blue frame surrounding both list boxes. 

The form that inherits from the ancestor now contains about twenty lines of text - and that's all! The only things that differ between various descendant forms are their captions and the specific queries for loading the list boxes and saving the changes.

type TAddXtraRateActs = class(TDualListBox) private public procedure Execute (anxtra: longint; const aname: string); end; implementation {$R *.dfm} uses managedm; Procedure TAddXtraRateActs.Execute (anxtra: longint; const aname: string); begin dm.ProgLog (178); LeftID:= anxtra; caption:= ' הוספת פעילויות לבונוס עבור ' + aname; qDistList.sql.text:= 'select activities.name, activities.id ' + 'from activities inner join xtrarateact ' + 'on activities.id = xtrarateact.act ' + 'where xtrarateact.xtra = :LeftID'; qSrchList.sql.text:= 'select activities.id, activities.name ' + 'from activities where not exists ' + '(select 1 from xtrarateact ' + 'where xtrarateact.act = activities.id ' + 'and xtrarateact.xtra = :LeftID)'; qInsert.sql.text:= 'insert into xtrarateact (xtra, act) ' + 'values (:LeftID, :RightID)'; qDelete.sql.text:= 'delete from xtrarateact where xtra = :LeftID ' + 'and act = :RightID'; Initialise; // load the lists only after there is valid SQL in the queries showmodal end;

That's it! Converting existing forms to this new format is a bit awkward but not difficult. It is important during the change-over to guard the sql statements from being lost, although I do have backups in the form of the original non-unicode program.



This day in blog history:

Blog #Date TitleTags
12331/03/2008Lots of things to doProgramming, Psychology, Van der Graaf Generator, Ian Rankin, Dog, DVD, Brian Viner, Management exams
34431/03/2011Intellectual stimulation and frustrationERP, MBA, HRM, Dan Ariely
46731/03/2012Sequencing "Darkness" / 2MIDI, Van der Graaf Generator, Home recording
81931/03/2015New mobile computerComputers

No comments: