ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 03.02.2000

Diese Seite wurde zuletzt aktualisiert am 03.02.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicAddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zur AVB-Web-Site, Kontakt und Impressum

Zurück...

Zurück...

(-hg) mailto:hg_listboxmask@aboutvb.de

Eine sortierte ListBox ist ja gut und schön - und nullkommanix eingerichtet, wenn Sie die Sorted-Eigenschaft auf True setzen. Dann werden Die Einträge in der ListBox fein säuberlich sortiert dargestellt und nachträglich neu hinzukommende Einträge passend einsortiert - nach allen Regeln der... ja, nach welchen Regeln eigentlich? Zunächst brav alphabetisch bzw. im Prinzip lexikalisch. Das bedeutet, dass Umlaute usw. wie der Stammlaut des Umlauts (ä wie a usw.) behandelt werden - es gibt aber auch andere Sortierregeln. Doch bei Zahlen sieht die Sortierung etwas eigenartig aus: 1 kommt vor 10 kommt vor 2 kommt vor 20... Das ist zwar nach der schlichten Regel der alphabetischen Einordnung von Ziffern und Zahlen völlig korrekt, aber ganz und gar nicht zufriedenstellend. Bei Datums-Angaben kommt die Sortierung gleichfalls gehörig ins Schleudern.

Sie können sich natürlich hinsetzen, ein wenig Informatik-Grundkenntnisse pauken und an Sortier-Algorithmen mit so klingenden Namen wie Quick-Sort, Bubble-Sort und dergleichen herumtüfteln. Fertigen Visual Basic-Code für diese Algorithmen werden Sie schnell finden, die Anpassung eine ListBox und die Einbeziehung derselben wird Ihnen dann allerhöchstens ein paar wenige Stunden Kopfzerbrechen bereiten. Den gleichen Weg werden Sie offensichtlich beschreiten müssen, wenn Sie die Einträge in der ListBox nach Kriterien sortieren wollen, die nicht auf dem dargestellten Text der Einträge, sondern etwa auf dem Inhalt der ItemData-Werte, die Sie ja jedem ListBox-Eintrag zuordnen können.

Klingt Ihnen das zu kompliziert? Nun, dann benutzen Sie doch einfach trotzdem eine sortierte ListBox. Sie stellen einfach das Sortierkriterium bzw. den Sortierschlüssel vor den eigentlichen Text eines ListBox-Eintrags, setzen ein Tabulatorzeichen (vbTab) dazwischen und... Sieht nicht so toll aus, finden Sie? Sie haben recht, der Anwender soll ja die Sortierschlüssel nicht sehen. Wenn es aber eine Möglichkeit gäbe, die Einträge so weit nach links aus der ListBox heraus zu verschieben, bis die vorangestellten Sortierschlüssel verschwunden sind, hätten wir die Lösung. Leider gibt es eine solche Möglichkeit nicht. Es sei denn, Sie fangen an, die ListBox-Einträge selbst zu zeichnen - mit ein "paar" API-Techniken ist das durchaus möglich. Aber dann könnten Sie auch ebenso den Weg der manuellen Sortiererei beschreiten, der Aufwand ist in beiden Fällen nicht trivial und hält sich die Waage. Der Ansatz, die ListBox-Einträge zu verschieben, fällt also wohl unter den Tisch.


Mit dem Steuerelement ListBoxMask verdecken Sie die Schlüsselbegriffe, anhand derer die Einträge in der ListBox sortiert werden

Die relativ einfach zu bewerkstelligende Lösung lautet: Sie decken den Teil der Sortierschlüssel der ListBox-Einträge ab. Ganz so trivial, wie einfach eine PictureBox oder dergleichen über die linke Seite der ListBox zu legen, ist das natürlich nicht. Der ListBox käme ja der linke Rand abhanden - wie sähe denn das bloß aus...!

Aber mit Hilfe von UserControls kommen Sie zum Ziel. Ein UserControl (das eigentliche, öffentliche "ListBoxMask" genannte Control) enthält weiteres UserControl ("ucBorder" genannt und nicht öffentlich) mit einem Rahmen (BorderStyle = 1), das den neuen linken Teil des ListBox-Rahmens liefert. Dieses UserControl mit dem Rahmen (ucBorder) wird bis knapp an die rechte Kante des Träger-UserControls (ListBoxMask) geschoben, wobei sein rechter Rand beliebig weit nach rechts ins Leere hinausragt, aber seine linke Kante noch vollständig sichtbar ist. Diese Anordnung wird automatisch im Ereignis UserControl_Resize von ListBoxMask vorgenommen.

Jetzt brauchen Sie dieses ListBoxMask-Control nur noch über eine ListBox zu legen und die Höhe und die linke Kante mit dieser in Übereinstimmung zu bringen. Durch Verschieben der rechten Kante von ListBoxMask stellen Sie nun ganz einfach die gewünschte Überdeckung ein.

Als Voreinstellung der Maskenfarbe wird beim ersten Anlegen eines ListBoxMask-Controls die Hintergrundfarbe des Containers (Ambient.BackColor) automatisch vorgewählt. Als Hintergrundfarbe (Füllfarbe) des Rahmen-Controls ucBorder ist vbWindowBackground voreingestellt - das entspricht der voreingestellten Hintergrundfarbe einer ListBox. Beide Farben können Sie in den Eigenschaften MaskColor und MarginColor beliebig ändern. Letztere Eigenschaft habe ich MarginColor genannt, weil Sie über die Eigenschaft MarginWidth festlegen können, wie viel vom ucBorder-Control sichtbar werden soll. Ist es breiter, als seine reine Rahmenbreite, wirkt seine Füllung wie eine linke Randspalte, die in der Hintergrundfarbe der ListBox eine weitere Abdeckungsmöglichkeit bietet. Allerdings reichen dann sowohl Selektionsbalken als auch das Fokus-Rechteck nicht mehr bis an den linken Rahmen heran und wirken abgeschnitten. Ich wollte Ihnen jedoch nicht diese zusätzliche Gestaltungsmöglichkeit vorenthalten.

Über die Eigenschaft Appearance können Sie die Rahmendarstellung an die der ListBox anpassen. In der Einstellung lbm3D sorgt Sie wie bei der ListBox für die übliche plastische Darstellung, in der Einstellung lbm2D für eine flache Kontur.

Zur Kontrolle der Überdeckung können Sie die Eigenschaft ShowMask auf False setzen - das ListBoxMask-Control wird transparent. Im Entwicklungsmodus zeigt eine Linie am rechten Rand die Überdeckung an, zur Laufzeit ist diese Linie nicht sichtbar - die Wirkung ist dieselbe, als ob Sie das Control über seine Visible-Eigenschaft unsichtbar gemacht hätten.

Die Maskierungsfläche ist natürlich keine tote Fläche in Ihren Forms. Sie können zum einen die ListBox samt ListBoxMask-Control soweit nach links auch aus dem Form hinausschieben, bis Sie eine "normale" ListBox-Position erhalten. Sie können auch andere Steuerelemente über der Maskierungsfläche anordnen. Da ListBoxMask allerdings ein vollwertiges Steuerelement sein muss, um eine ListBox überdecken zu können, kann es nicht von den grafischen Steuerelementen wie Shape, Line und Label überdeckt werden. Da es aber als Control-Container ausgelegt ist, kann es solche Steuerelemente selbst aufnehmen. Diese können dann allerdings nicht über die Grenzen von ListBoxMask hinausragen. Sollte dies für die Gestaltung Ihres Forms notwendig sein, müssen Sie wohl oder übel ein Frame-Steuerelement mit BorderStyle gleich 0 darüber legen und zur Positionierung grafischer Steuerelemente verwenden, oder diese gegebenenfalls so zu sagen "gestückelt" anordnen - ein Element innerhalb von ListBoxMask, ein weiteres exakt angepasst außerhalb angesetzt.

Außerdem werden alle Maus-relevanten Ereignisse wie Click, DblClick, MouseDown , MouseMove und MouseUp weitergereicht und gleich in die Koordinaten des Containers umgerechnet. Wundern Sie sich aber nicht, dass die X und Y-Werte "exakter" als die des umgebenden Forms erscheinen - Visual Basic rechnet intern etwas anders als das COM-System, das für Steuerelemente zuständig ist. Dieses rechnet mit einer wesentlich höheren Auflösung (vbHimetric). Ginge es nur um die gegebenenfalls notwendige einfache Umrechnung von Pixels in Twips, hätte ich eine VB-analoge Rundung einbauen können. Da sich die Umrechnung jedoch flexibel jedem Container anpassen sollte, habe ich dies bewusst unterlassen (private Funktion zConvertToContainer). Sie können die Single-Werte der X- und Y-Koordinaten selbst per Konvertierung mit CLng glätten.

Schließlich werden auch noch die Ereignisse OLEDragOver und OLEDragDrop weitergereicht, wenn Sie in der Eigenschaft OLEDropMode lbmOLEDropManual wählen, oder wenn Sie lbmOLEDropContainer wählen und der Container entsprechend eingestellt ist.

Beim Auslesen der ListBox-Einträge mit dem vorangestellten Schlüssel ist auch nicht weiter schwierig. Sie suchen die Position des Tabulator-Zeichens und trennen den Eintrag an dieser Stelle in Schlüssel und eigentlichen Eintrag:

Dim nKey As String
Dim nValue As String
Dim nItem As String
Dim nTabPos As Integer

nItem = ListBox.List(Index)
nTabPos = InStr(nItem, vbTab)

nKey = Left$(nItem, nTabPos -1)
nValue = Mid$(nItem, nTabPos + 1)

Das ListBoxMask-Control ist beidermaßen für Visual Basic 5 als auch Visual Basic 6 geeignet. Da jedoch in VB 5 die Appearance-Eigenschaft zur Laufzeit schreibgeschützt ist, habe ich zwei verschiedene Versionen daraus gemacht. Leider gilt also für die VB 5-Version der obenstehende Abschnitt zur Eigenschaft Appearance nicht. Wenn Sie dennoch unbedingt eine 2D-Darstellung brauchen, können Sie ja gegebenenfalls die Einstellung des ucBorder-Controls zur Entwicklungszeit ändern und das OCX für VB 5 neu kompilieren. Wenn Sie in den Projekteigenschaften im Register "Komponente" die Binär-Kompatibilität wählen, gibt es keinerlei Probleme damit, da die Schnittstelle(n) des Controls nach außen hin von dieser Maßnahme unberührt blieben.


Code des Controls ListBoxMask Code des Controls ListBoxMask

ListBoxMask - Code und OCX für VB 6 (listboxmask6.zip - ca. 23 KB)

ListBoxMask - Code und OCX für VB 5 (listboxmask5.zip - ca. 16 KB)



Komponenten-Übersicht

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2023 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...