|
In einem Dateisystem etwa darf jeder Name für eine Datei oder einen Ordner nur einmal in einem Ordner auftreten. Wenn Sie eine Dateisystem-Struktur in ein TreeView-Steuerelement aus den Microsoft Common Controls einlesen, ist diese Namens-Einmaligkeit bereits gegeben. Sobald Sie jedoch von Ihrer Anwendung aus weitere Knoten (und damit Dateien oder Ordner) einfügen wollen, oder wenn die Namen der Knoten vom Anwender bearbeitet werden können, muss sicher gestellt werden, dass auch danach jeder Name weiterhin einmalig ist. Bei einem Dateisystem können Sie natürlich die Kontrolle darüber diesem überlassen und gegebenenfalls dessen Fehlermeldungen auswerten. Wenn Sie aber eine eigenständige Struktur in einem TreeView-Steuerelement verwalten möchten, benötigen Sie einen eigenen Mechanismus zur Gewährleistung einmaliger Knotennamen in jedem Zweig. Der sicherste Ansatz ist, vom Anwender oder von vorherigem Code vergebene Namen zunächst auf ihre Einzigartigkeit hin zu prüfen. Stellt sich dabei heraus, dass der neue Name eine Doublette wäre, gibt es mehrere Möglichkeiten, damit umzugehen. Sie können den neuen Namen verwerfen. Hat der Anwender ihn im TreeView geändert, können Sie in dessen AfterLabelEdit-Ereignis den Parameter Cancel auf True setzen, so dass die Bearbeitung rückgängig gemacht wird. Sie können zudem die Bearbeitung per Aufruf der StartLabelEdit-Methode den Bearbeitungsmodus erneut starten - vielleicht sogar so lange, bis der Anwender einen einmaligen Namen eingegeben hat. Die Prüfung auf Einmaligkeit erledigt die folgende Hilfsfunktion. Sie untersucht einfach die Namen der Knoten auf der gleichen Ebene ("Siblings").
Public Enum NodeUniqueCompareMethodConstants
nuCompareBinary
nuCompareText
End Enum
Public Function IsNodeTextUnique(Node As Node, Text As String, _
Optional ByVal CompareMethod As NodeUniqueCompareMethodConstants _
= nuCompareText) As Boolean
Dim nNode As Node
Set nNode = Node.FirstSibling
Do
If Not nNode Is Node Then
If StrComp(nNode.Text, Text, CompareMethod) = 0 Then
Exit Function
End If
End If
Set nNode = nNode.Next
Loop Until nNode Is Nothing
IsNodeTextUnique = True
End Function
Sie können aber auch gleiche Namen einfach durchnummerieren oder mit einem unterscheidbaren Zusatz versehen und vorläufig verwenden: X Die folgende Funktion NodeUniqeText prüft nicht nur die Einmaligkeit eines Namens, sondern gibt gleich eine einmalige, modifizierte Variante des im Parameter NewText übergebenen Namens zurück. Über den optionalen Parameter PrefixNumberMode können Sie festlegen, ob dem modifizierten Namen ein Standardzusatz (Konstante kDefaultNodePrefix oder ein anderer im optionalen Parameter Prefix angegebener Zusatz) vorangestellt wird, oder ob eine Nummerierung erfolgt.
Public Enum NodeUniquePrefixNumberModeConstants
nuNumbers
nuPrefix
End Enum
Private Const kDefaultNodePrefix = "Kopie von "
Public Function NodeUniqueText(Node As Node, NewText As String, _
Optional ByVal CompareMethod As NodeUniqueCompareMethodConstants _
= nuCompareText, Optional ByVal PrefixNumberMode _
As NodeUniquePrefixNumberModeConstants = nuNumbers, _
Optional Prefix As String = kDefaultNodePrefix) As String
Dim nNode As Node
Dim nText As String
Dim nCount As String
nText = NewText
Select Case PrefixNumberMode
Case nuNumbers
nCount = 1
Do
If IsNodeTextUnique(Node, nText, CompareMethod) Then
Exit Do
Else
nCount = nCount + 1
nText = NewText & "(" & nCount & ")"
End If
Loop
Case nuPrefix
Do
If IsNodeTextUnique(Node, nText, CompareMethod) Then
Exit Do
Else
nText = Prefix & nText
End If
Loop
End Select
NodeUniqueText = nText
End Function
Einen neuen Knoten mit einem einmaligen Namen können Sie beispielsweise so einfügen:
Private Sub cmdNodeNew_Click()
Dim nNode As Node
With TreeView1
Set nNode = .Nodes.Add()
With nNode
Select Case True
Case optModeConstants(0).Value
.Text = NodeUniqueText(nNode, "Neuer Knoten")
Case optModeConstants(1).Value
.Text = NodeUniqueText(nNode, "Neuer Knoten", , nuPrefix)
End Select
.Selected = True
End With
.StartLabelEdit
End With
End Sub
Und im AfterLabelEdit-Ereignis können sie etwa wie folgt reagieren:
Private Sub TreeView1_AfterLabelEdit(Cancel As Integer, _
NewString As String)
With TreeView1
If chkReject.Value Then
If Not IsNodeTextUnique(.SelectedItem, NewString) Then
.StartLabelEdit
Cancel = True
End If
Else
Select Case True
Case optModeConstants(0).Value
NewString = NodeUniqueText(.SelectedItem, NewString)
Case optModeConstants(1).Value
NewString = NodeUniqueText(.SelectedItem, NewString, _
, nuPrefix)
End Select
End If
End With
End Sub
|