Session D-CTRL

Komplexe Controls

Sebastian Flucke
ASCI-Consulting


EINLEITUNG


Einführung

 

Die List- und ComboBoxen in Visual FoxPro sind sehr komplexe Controls, die vielfältige Möglichkeiten in sich bergen.Dabei sind folgende prinzipielle Neuigkeiten gegenüber FoxPro für Windows 2.6 zu verzeichnen:

Ein programmtechnischer Wermutstropfen ist dabei die Tatsache, daß das List- bzw. ComboBox-Control im Gegensatz zum Grid kein Container mit eigenständigen Elementen ist.

Das hat zur Folge, daß bestimmte Funktionalitäten wie z.B. Mehrspaltigkeit nur über etwas "ungewöhnliche" Wege erreicht und programmtechnisch gesteuert werden können.

Detaillierte Bemerkungen zu den List- und ComboBox-spezifischen Properties, Events und Methoden sind auf der Begleitdiskette in der Datenbankdatei LSTPROT1.DBF abgelegt.

 

Die folgenden mit List- und ComboBoxen in Zusammenhang stehenden Begriffe tauchen in der deutschen Version von Visual FoxPro auf und werden aus Eindeutigkeitsgründen im vorliegenden Artikel ausschließlich in ihren englischen Entsprechungen verwendet:
VFP-deutsch VFP-englisch
Listenfeld ListBox
Kombinationsfeld ComboBox
Datenfeld Array
ElementNr ItemId
Index Index
Eigenschaft Property

Die funktionellen Unterschiede zwischen List- und ComboBox drücken sich in einer Reihe von Unterschieden bzgl. der Properties, Events und Methoden aus:
nur ComboBox nur ListBox
Alignment MoverBars
BackColor MultiSelect
DropDown-Event  
ForeColor  
Margin  
SelectedBackColor  
SelectedForeColor  
SelLength  
SelStart  
SelText  
Style  

Die comboBox-spezifischen Eigenschaften hängen im wesentlichen mit dem textBox-artigen Teil der ComboBox zusammen (ohne daß man allerdings vollständig alle äquivalenten Eigenschaften einer TextBox wiederfindet, es fehlen z.B. InputMask, HideSelection u.a.).

Die listBox-spezifischen Eigenschaften beziehen sich ausschließlich auf die Mehrfachauswahl und die Möglichkeit, Einträge einer ListBox per Maus umzusortieren.

Auf die Einträge in List-/ComboBoxen kann über zwei Wege zugegriffen werden:

Für die meisten Methoden und Properties, die eine Spezifizierung des zu bearbeitenden Eintrags erfordern, existiert jeweils eine Variante, bei der der "Index" anzugeben ist und eine Variante, die eine "ItemId" erwartet:
arbeitet mit Index arbeitet mit ItemId
AddItem AddListItem
IndexToItem ItemToIndex
ItemData ItemIdData
List ListItem
ListIndex ListItemId
NewIndex NewItemId
Picture <keine Entsprechung>
RemoveItem RemoveListItem
Selected SelectedId
TopIndex TopItemId

Die Pendants der jeweiligen Properties und Methoden funktionieren in den meisten Fällen identisch (Ausnahme: AddItem fügt in jedem Fall Einträge hinzu, während AddListItem unter bestimmten Bedingungen bestehende Einträge ersetzt).

Die Properties ItemData/ItemIdData, List/ListItem, Picture und Selected/SelectedId beinhalten array-ähnliche Strukturen, auf die mit "Index" oder "ItemId" zugegriffen werden kann.

Auf die vorgenannten Properties kann nicht(!) mit den VFP-Array-Befehlen und -Funktionen (z.B. ASCAN() usw.) zugegriffen werden.

List- und ComboBoxen können für folgende Zwecke eingesetzt werden:

Bei dem Einsatz von List- und ComboBoxen als Auswahl-Element unterscheidet man:

Beispiele für Listboxen für Auswahlprozesse mit direkt ausgelöster Aktivität:

ComboBox als Voreinstellung für später auszuführende Aktivitäten:

ListBox als reines Anzeige-Element:

Die Datenquelle von List- und ComboBoxen wird in dem RowSourceType-Property definiert. In VisualFoxPro stehen für List- und ComboBoxen folgende 10 Datenquellen zur Verfügung:

Die Beschreibung des konkreten Inhalts einer List- bzw. Combobox entsprechend RowSourceType wird mit dem RowSource-Property festgelegt.

Bei RowSourceType = 2, 3, 4, 5, 6 können die Datenquellen neben dem Datentyp "C" auch vom Datentyp "N" oder "L" sein (sie werden dann automatisch in den Datentyp "C" gewandelt).

Diese automatische Datentyp-Wandlung von "N" zu "C" ist allerdings problematisch, wenn die gewandelten Zahlen mehr oder weniger viele führende Leerzeichen haben. Da die Texte in den Spalten linksbündig angezeigt werden, führen diese Leerzeichen u.U. zu nicht untereinanderstehenden Dezimalstellen (siehe LST8.SCX). Einziger Ausweg ist die Verwendung eines nichtproportionalen Fonts.

Memo- oder General-Felder sind als Datentypen für List-/ComboBoxen nicht möglich.

Änderungen von RowSourceType zur Laufzeit bewirken eine sofortige Umdefinition der List-/ComboBox, u.U. mit Syntaxerror-Folgen, wenn die RowSource noch nicht umgestellt war, deshalb beim Umdefinieren von RowSourceType zur Laufzeit wie folgt vorgehen:

Je nach Verwendungszweck einer List-/ComboBox ist eine ControlSource notwendig oder auch nicht.

Allgemein laßt sich sagen, daß bei konsequenter Verwendung objektorientierter Programmiermethoden eine ControlSource nur noch in Ausnahmefällen benötigt wird.

Wird jedoch eine ControlSource verwendet, so hat sie einige Wechselwirkungen mit den Properties Value, DisplayValue, ListIndex und ListItemId.

Zugelassene Datentypen für eine ControlSource sind "C" und "N", andere Datentypen führen zu einem Laufzeitfehler.

Der Datentyp und der Inhalt der ControlSource bestimmt den Datentyp und den Inhalt des Value-Property (wird der Datentyp oder der Inhalt der ControlSource geändert, so ändert sich der Datentyp bzw. der Inhalt des Value-Property und umgekehrt).

Das DisplayValue-Property verwaltet seinen Datentyp und seinen Inhalt allerdings unabhängig von Value und ControlSource.

Für ControlSource, Value und DisplayValue gilt:

Wird die ControlSource, das Value-Property oder das DisplayValue-Property auf einen Wert gesetzt, zu dem kein passender Eintrag existiert, so stehen ListIndex und ListItemId auf 0, die ControlSource sowie Value und DisplayValue werden je nach Datentyp auf 0 oder "" (leere Zeichenkette) gesetzt.

Folgende Besonderheit von Controlsource und DisplayValue- bzw. Value-Property ist zu beachten:

Ein weiterer eigenartiger Zustand kann entstehen, wenn man in eine ListBox hineinklickt und bei gedrückter Maustaste den Mauscursor wieder aus der ListBox herauszieht. In diesem Fall werden ListIndex und ListItemId mit 0 belegt, aber die ControlSource sowie das Value- und das DisplayValue-Property behalten die Werte bei, die sie vor dieser Operation hatten (was wiederum zu überraschenden Konstellationen führen kann)!

Achtung! In dieser Situation wird kein InteractiveChange- oder ProgrammaticChange-Event ausgelöst!

Zur Gestaltung mehrspaltiger List-/ComboBoxen sind folgende Properties relevant:

Unter Beachtung bestimmter Voraussetzungen können List-/ComboBoxen zur Visualisierung von 1:n-Beziehungen benutzt werden.

Hinter dem Hilfe-Topic "Aktualisieren einer 1:n-Anzeige, die auf einem Listenwert basiert" verbirgt sich die Beschreibung, wie man mit einer List-/ComboBox einen Datensatz in einer Masterdatei auswählt und alle zugehörigen Detail-Datensätze in "anderen" Dialogelementen angezeigt bekommt.

Dieses "andere" Dialog-Element kann nur ein Dialogelement sein, welches Informationen aus mehreren Datensätzen anzeigen kann (also nur Grid, ListBox oder ComboBox). Die im Hilfetopic beschriebene Verfahrensweise funktioniert allerdings nur mit dem Grid, mit List- oder ComboBoxen als Child-Elementen wirkt der Mechainsmus leider nicht (siehe LST7.SCX).

Möchte man trotzdem in einer ListBox Child-Informationen anzeigen, so kann man z.B. einen Filter (am besten rushmore-optimierbar) verwenden (siehe LST6.SCX, InteractiveChange-Event).

Das in der VFP-Hilfe unter dem Topic "Anzeigen von Detail-Datensätzen in einer Liste" beschriebene Verfahren unter Verwendung eines Select-Befehls ist nur bedingt geeignet, weil das Requery der Detail-ListBox je nach Datenkonstellation ziemlich lange Reaktionszeiten bedeuten kann.

In List- und ComboBoxen kann den eigentlichen Einträgen in jeder Zeile eine Bitmap vorangestellt werden. Zu diesem Zweck kann das Picture-Property für jeden Eintrag mit dem Namen einer BMP- oder ICO-Datei gefüllt werden (auf das Picture-Property kann analog dem List-Property mit dem "Index" zugegriffen werden). Bei ComboBoxen wird das entsprechende Bild allerdings nur in der aufgeklappten Liste angezeigt, nicht(!) in der zugehörigen Anzeigebox. Laut Dokumentation soll dem Picture-Property auch der Inhalt eines General-Feldes zugewiesen werden können, aber das war nicht nachzuvollziehen (Fehler 1912: "Operation ist für ein Objektfeld nicht zulässig."). Die Bitmaps werden in ihrer vollen Größe ohne irgendwelche Anpassungen angezeigt. Sie beeinflussen damit auch die Größe der einzelnen Einträge, die dadurch unterschiedlich hoch sein können. Das führt in bestimmten Konstellationen zu unerwünschten Überblendungseffekten, wenn eine solche ListBox gescrollt wird. Ebenfalls ist Vorsicht geboten bei der kombinierten Verwendung von Bitmaps und MoverBars. Auch in diesem Fall kommt es zu unschönen optischen Effekten.

Das Event-Verhalten von List- und ComboBoxen ist ein äußerst komplizierter Ablauf. Je nach Art der Bedien-Aktivität (Maus-Klick, Maus-Doppel-Klick, Tastatur-Navigation) unterscheidet sich das Event-Verhalten sehr stark und birgt auch so einige Überraschungen. Mit den Beispielen LST2.SCX (ListBox) und LST3.SCX (ComboBox) kann das Event-Verhalten gut erforscht werden.

Für das Positionieren von Programm-Code in die richtigen Events ist es deshalb unumgänglich, sich mit der diesbezüglichen Verhaltensweise von List- und ComboBoxen experimentell vertraut zu machen. Neben der Frage, bei welcher Aktivität welcher Event ausgelöst wird, ist außerdem noch die Auslöse-Reihenfolge und die Auslösehäufigkeit wichtig (letzteres, um unbeabsichtigte Kumulationen zu vermeiden). Im folgenden sind einige der wesentlichsten Erkenntnisse zusammengestellt:

Weitere relevante Events sind MouseDown, MousUp, InteractiveChange, When, Valid, GotFocus, LostFocus.