Setzen Sie bei einer ListBox die Eigenschaft Style auf "1 - Kontrollkästchen", so erscheinen vor den Einträgen in der ListBox CheckBoxen. Klickt der Anwender auf eine dieser CheckBoxen, wird das Ereignis ItemCheck ausgelöst. Hier haben Sie die Möglichkeit entsprechend zu reagieren. Eine eingebaute Möglichkeit, die Änderung durch den Anwender zu verhindern, gibt es jedoch nicht.
Sie können jedoch an dieser Stelle die Änderung gezielt wieder rückgängig machen, indem Sie den Wert der Selected-Eigenschaft für das betreffende Element einfach wieder umkehren.
Private Sub List1_ItemCheck(Item As Integer)
With List1
.Selected(Item) = Not .Selected(Item)
End With
End Sub
Allerdings würden Sie damit auch verhindern, dass der Wert der Selected-Eigenschaft für ein Element per Code geändert werden kann. Sie brauchen also eine Möglichkeit zur Unterscheidung, ob die Änderung per Code oder durch den Anwender erfolgt ist. Dazu verwenden Sie eine Merk-Variable des Datentyps Boolean, die Sie beispielsweise im Allgemein-Teil des gleichen Forms deklarieren. Diese setzen Sie auf True, wenn Sie den Selected-Wert per Code setzen wollen:
Private mListCheckByCode As Boolean
mListCheckByCode = True
List1.Selected(Index)
mListCheckByCode = False
Die Ereignisprozedur ItemCheck modifizieren Sie wie folgend, um dort die Unterscheidung zu treffen:
Private Sub List1_ItemCheck(Item As Integer)
If Not mListCheckByCode Then
With List1
.Selected(Item) = Not .Selected(Item)
End With
End If
End Sub
Wenn Sie nur einzelne und bestimmte Elemente vor einer Änderung durch den Anwender schützen wollen, gibt es zwei Möglichkeiten. Zum einen können Sie im ItemCheck individuell anhand des übergebenen Element-Index prüfen, ob die Änderung wieder rückgängig gemacht werden soll.
Private Sub List1_ItemCheck(Item As Integer)
If Not mListCheckByCode Then
' If Prüfung erfolgreich...
With List1
.Selected(Item) = Not .Selected(Item)
End With
End If
End Sub
Andererseits können Sie aber auch ein Element individuell als "gesperrt" markieren. Drei Möglichkeiten bieten sich hierzu an. Falls Sie nicht in der ItemData-Eigenschaft zu jedem Element zusätzliche Daten ablegen, können Sie diese zur Markierung verwenden und ihr als Sperrmarkierung den Wert True (-1) zuweisen:
List1.ItemData(BetreffenderIndex) = True
Und nun die Prüfung:
Private Sub List1_ItemCheck(Item As Integer)
If Not mListCheckByCode Then
With List1
If .ItemData(Index) Then
.Selected(Item) = Not .Selected(Item)
End If
End With
End If
End Sub
Falls Sie Sie die ItemData-Eigenschaft für andere Zwecke benötigen, aber beispielsweise sicher sein oder es so einrichten können, dass Sie nur positive Werte verwenden, können Sie als Markierung negative Werte verwenden. Sie multiplizieren Sie dazu einfach den ItemData-Wert mit -1. Falls aber ItemData den Wert 0 enthalten sollte, wäre eine Multiplikation mit -1 ja sinnlos. Daher sollten Sie stattdessen irgendeinen anderen Wert als "0" festlegen, den sie ansonsten im positiven Bereich nicht benötigen, und dann entsprechend interpretieren.
Für ein schlichtes Umschalten der Sperrung reicht eine schlichte Multiplikation mit -1:
With List1
.ItemData(BetreffenderIndex) =.ItemData(BetreffenderIndex) * -1
End With
Zum gezielten Setzen der Sperrung, unabhängig vom vorherigen Zustand, multiplizieren Sie den absoluten Wert mit -1:
With List1
.ItemData(BetreffenderIndex) = _
Abs(.ItemData(BetreffenderIndex)) * -1
End With
Und zum gezielten Aufheben der Sperrung, ebenfalls unabhängig vom vorherigen Zustand, setzen Sie einfach den absoluten Wert:
With List1
.ItemData(BetreffenderIndex) = Abs(.ItemData(BetreffenderIndex))
End With
Die Auswertung dazu im ItemCheck-Ereignis sähe nun so aus:
Private Sub List1_ItemCheck(Item As Integer)
If Not mListCheckByCode Then
With List1
If Sign(.ItemData(Index)) = -1 Then
.Selected(Item) = Not .Selected(Item)
End If
End With
End If
End Sub
Um einen solchermaßen zur Sperrmarkierung mitverwendeten ItemData-Wert auch wieder wie gewohnt nutzen zu können, verwenden Sie immer den absoluten Wert und interpretieren gegebenenfalls den erwähnten "0"-Ersatz. Angenommen, Sie haben den größtmöglichen positiven Wert als Ersatz gewählt (&H7FFFFFFF bzw. 2147483647):
Dim nItemData As Long
nItemData = Abs(List1.ItemData(BetreffenderIndex))
If nItemData = &H7FFFFFFF Then
nItemData = 0
End If
Die dritte Möglichkeit der Sperrmarkierung besteht darin, ein nicht sichtbares Zeichen an das Element anzuhängen. Dieses müssen Sie natürlich bei der normalen Verwendung des Elements immer zunächst entfernen. Ein solches Zeichen wäre beispielsweise das Tabulator-Zeichen. Die Sperrung:
Dim nListItem As String
With List1
nListItem = .List(BetreffenderIndex)
If Right$(nListItem, 1) <> vbTab then
.List(BetreffenderIndex) = nListItem & vbTab
End If
End With
Die Aufhebung:
Dim nListItem As String
With List1
nListItem = .List(BetreffenderIndex)
If Right$(nListItem, 1) = vbTab then
.List(BetreffenderIndex) = Mid$(nListItem, Len(nListItem) - 1)
End If
End With
Und die Umkehrung:
Dim nListItem As String
With List1
nListItem = .List(BetreffenderIndex)
If Right$(nListItem, 1) = vbTab then
.List(BetreffenderIndex) = Mid$(nListItem, Len(nListItem) - 1)
Else
.List(BetreffenderIndex) = nListItem & vbTab
End If
End With
Im ItemCheck-Ereignis sähe die Prüfung nun so aus:
Private Sub List1_ItemCheck(Item As Integer)
If Not mListCheckByCode Then
With List1
If Right$(nListItem, 1) = vbTab then
.Selected(Item) = Not .Selected(Item)
End If
End With
End If
End Sub
Zur normalen Verwendung ohne das möglicherweise angehängte Sperrzeichen können Sie den gleichen Code wie zur Aufhebung der Sperrung verwenden.
|