Hallo AutoIt-Gemeinde,
zur Zeit verzweifle ich an einem seltsamen TreeView-Event-Problem. Und zwar habe ich folgendes vor:
Zur
Software-Installation möchte ich mittels eines TreeViews dem Nutzer die
Möglichkeit geben, alle gewünschten Komponenten selbst auszuwählen.
Also in diesem TreeView werden einige Hauptkomponenten dargestellt. Und
jede Hauptkomponente hat mehrere Sub-Komponenten. Das Auswahlverhalten
soll wie folgt sein. Wählt der Nutzer eine Hauptkomponente, werden von
dieser auch alle Sub-Komponenten ausgewählt. Soll heißen, alle
Kind-Items werden auf Checked gesetzt. Weiter soll, wenn ein einzelnes
Kind-Element ausgewählt wird, werden auch alle Eltern-Items davon auf
Checked gesetzt.
Die TreeViewItems erzeuge ich einfach mit:
[autoit]
$treeView = GUICtrlCreateTreeView(16, 192, 465, 326, BitOR($GUI_SS_DEFAULT_TREEVIEW,$TVS_CHECKBOXES))
$mainItem1 = GUICtrlCreateTreeViewItem("Main 1", $treeView)
GUICtrlSetOnEvent(-1,"SelectionChangedChildItem")
$subItem1 = GUICtrlCreateTreeViewItem("Sub 1", $mainItem1 )
GUICtrlSetOnEvent(-1,"SelectionChangedChildItem")
$subItem2 = GUICtrlCreateTreeViewItem("Sub 2", $mainItem1 )
GUICtrlSetOnEvent(-1,"SelectionChangedChildItem")
Und die Implementierung des Event-Handling ist wie folgt:
[autoit]
Func SelectionChangedChildItem()
SetCheckedForAllChildItems(@GUI_CtrlId)
SetCheckedForParentItem(@GUI_CtrlId)
EndFunc
Func SetCheckedForParentItem($hChildItem)
Local $hParent = _GUICtrlTreeView_GetParentHandle ($TreeView1, $hChildItem)
If $hParent <> 0 Then
If _GUICtrlTreeView_GetChecked($TreeView1, $hChildItem) Then
_GUICtrlTreeView_SetChecked($TreeView1, $hParent)
Else
Local $hChild
Local $childCount = _GUICtrlTreeView_GetChildCount($TreeView1, $hParent)
If $childCount > 0 Then
Local $isAnyChildChecked = false
For $i = 1 To $childCount
If $i = 1 Then
$hChild = _GUICtrlTreeView_GetFirstChild($TreeView1, $hParent)
Else
$hChild = _GUICtrlTreeView_GetNextSibling($TreeView1, $hChild)
EndIf
$isAnyChildChecked = BitOR($isAnyChildChecked, _GUICtrlTreeView_GetChecked($TreeView1, $hChild))
Next
_GUICtrlTreeView_SetChecked($TreeView1, $hParent, $isAnyChildChecked)
EndIF
EndIF
SetCheckedForParentItem($hParent)
EndIf
EndFunc
Func SetCheckedForAllChildItems($hParentItem)
Local $hChild
Local $childCount = _GUICtrlTreeView_GetChildCount($TreeView1, $hParentItem)
Local $isChecked = _GUICtrlTreeView_GetChecked($TreeView1, $hParentItem)
If $childCount > 0 Then
For $i = 1 To $childCount
If $i = 1 Then
$hChild = _GUICtrlTreeView_GetFirstChild($TreeView1, $hParentItem)
Else
$hChild = _GUICtrlTreeView_GetNextSibling($TreeView1, $hChild)
EndIf
_GUICtrlTreeView_SetChecked($TreeView1, $hChild, $isChecked)
SetCheckedForAllChildItems($hChild)
Next
EndIf
EndFunc
Das
Setzten des Checked-Status funktioniert soweit ohne Probleme nur wenn
ein Item im TreeView eingeklappt wird kommt es zu einem seltsamen
Verhalten. Und zwar wird dann einmalig ebenfalls
"SelectionChangedChildItem" aufgerufen. Und dieses führt dazu, dass wenn
das Item welches eingeklappt wird auf Checked gesetzt ist, alle
Kind-Items davon ebenfalls auf Checked gesetzt werden. Wobei dieses
Verhalten nur beim !ersten! einklappen zu beobachten ist und auch nur,
wenn vorher des Checked-Status der Kind-Elemente geändert wurde.
Im obigen Beispiel wäre dies wie folgt:
Ich
habe eine Hauptkomponente "Main 1" mit zwei Sub-Komponenten "Sub 1" uns
"Sub 2". Wird "Sub 1" nun auch Checked gesetzt wird ebenfalls "Main 1"
auf Checked gesetzt. Soweit alles richtig. Nun setzte ich auch "Sub 2"
auf Checked, nichts weiter passiert. Alles i.O. Nun deaktiviere ich "Sub
1" wieder, also sind nur noch "Main 1" und "Sub 2" markiert bzw.
Checked. Wenn ich nun "Main 1" einklappe wird
"SelectionChangedChildItem" aufgerufen und da dieses den Checked-Status
von "Main 1" abfragt werden "Sub 1" und "Sub 2" auf Checked gesetzt.
Also meine Auswahl ist dahin. Nun kann ich "Main 1" aus- und einklappen
wie ich will "SelectionChangedChildItem" wird nicht mehr aufgerufen.
An
diesem Punkt komme ich einfach nicht mehr weiter, es scheint ja nur
einen Event für das ganze TreeViewItem-Handling zu geben bzw ich weiß
nicht, ob man irgendwie im Event unterscheiden kann, ob das Item nur
markiert bzw ein- oder ausgeklappt wurde.
Könnt Ihr mir da vielleicht bei diesem Problem weiter helfen?