- Offizieller Beitrag
Bei einem TreeView mit Checkboxen möchte man ja manchmal, dass die Haken auch für die Child-Items mitgesetzt werden.
Ich habe mal drei rekursive Funktionen geschrieben, die eine solche Funktionalität erreichen:
- Alle Child-Items des angehakten Items werden ebenfalls angehakt
- Alle Haken bei übergeordneten Parent-Items werden entfernt, wenn der Haken bei einem Item entfernt wird
- Überprüfung ob alle Sibling-Items ebenfalls angehakt sind und, wenn zutreffend, das übergeordnete Parent-Item anhaken
Schaut euch einfach das Beispiel an:
Spoiler anzeigen
#include<GUIConstantsEx.au3>
#include<GuiTreeView.au3>
#include<TreeViewConstants.au3>
#include<WindowsConstants.au3>
Global $hGui = GUICreate('TreeView-(Un)Checked-Example', 400, 600)
Global $hTreeView = GUICtrlCreateTreeView(5, 5, 390, 590, BitOR($GUI_SS_DEFAULT_TREEVIEW, $TVS_CHECKBOXES), $WS_EX_CLIENTEDGE)
Global $hRoot = GUICtrlCreateTreeViewItem('Root', $hTreeView)
_GUICtrlTreeView_SetBold($hTreeView, $hRoot)
_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 1 To 3
$hItem1 = _GUICtrlTreeView_AddChild($hTreeView, GUICtrlGetHandle($hRoot), StringFormat('[%02d] Child 1st Gen.', $x))
For $y = 1 To 3
$hItem2 = _GUICtrlTreeView_AddChild($hTreeView, $hItem1, StringFormat('[%02d] Child 2nd Gen.', $y))
For $z = 1 To 2
$hItem3 = _GUICtrlTreeView_AddChild($hTreeView, $hItem2, StringFormat('[%02d] Child 3rd Gen.', $z))
Next
Next
Next
_GUICtrlTreeView_EndUpdate($hTreeView)
_GUICtrlTreeView_Expand($hTreeView)
GUISetState()
While True
Switch GUIGetMsg()
Case $GUI_EVENT_PRIMARYDOWN ; (*)
$aInfo = GUIGetCursorInfo($hGui) ; (*)
If $aInfo[4] = $hTreeView Then ; (*)
$aAdjust = ControlGetPos($hGui, '', $hTreeView) ; (*)
If BitAND(_GUICtrlTreeView_HitTest($hTreeView, $aInfo[0]-$aAdjust[0]-2, $aInfo[1]-$aAdjust[1]-2), 64) Then ; (*)
$hSelect = _GUICtrlTreeView_GetSelection($hTreeView)
$checked = _GUICtrlTreeView_GetChecked($hTreeView, $hSelect)
$hItem = _GUICtrlTreeView_GetFirstChild($hTreeView, $hSelect)
If $hItem Then _SetChildItemsChecked($hTreeView, $hItem, $checked)
If $checked Then
_VerifySiblingItems($hTreeView, $hSelect)
Else
_SetParentItemsUnchecked($hTreeView, $hSelect)
EndIf
EndIf
EndIf
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
; (*) = diese Konstruktion ist notwendig, weil man sonst nicht zwischen einem Mausklick
; auf den Item-Text und der Checkbox unterscheiden kann
; Überprüft (rekursiv) ob alle Sibling-Items angehakt sind und setzt, wenn zutreffend, den Haken beim Parent-Item
Func _VerifySiblingItems($hTreeView, $hItem)
Local $hTmp, $hSave = $hItem, $iCount = _GUICtrlTreeView_GetSiblingCount($hTreeView, $hItem)
While True
$hTmp = _GUICtrlTreeView_GetNextSibling($hTreeView, $hItem)
If Not $hTmp Then ExitLoop
$hItem = $hTmp
WEnd
Do
If _GUICtrlTreeView_GetChecked($hTreeView, $hItem) Then $iCount -= 1
$hItem = _GUICtrlTreeView_GetPrevSibling($hTreeView, $hItem)
Until Not $hItem
If Not $iCount Then
Local $hParent = _GUICtrlTreeView_GetParentHandle($hTreeView, $hSave)
If $hParent Then
_GUICtrlTreeView_SetChecked($hTreeView, $hParent)
_VerifySiblingItems($hTreeView, $hParent)
EndIf
EndIf
EndFunc
; Setzt (rekursiv) den Haken bei allen Child-Items, wenn der Haken bei einem Item gesetzt wurde
Func _SetChildItemsChecked($hTreeView, $hItem, $checked)
Do
Local $hNewItem = _GUICtrlTreeView_GetFirstChild($hTreeView, $hItem)
If $hNewItem Then _SetChildItemsChecked($hTreeView, $hNewItem, $checked)
_GUICtrlTreeView_SetChecked($hTreeView, $hItem, $checked)
$hItem = _GUICtrlTreeView_GetNextChild($hTreeView, $hItem)
Until Not $hItem
EndFunc
; Entfernt (rekursiv) den Haken bei allen Parents, wenn der Haken von einem Item entfernt wurde
Func _SetParentItemsUnchecked($hTreeView, $hItem)
Local $hParent = _GUICtrlTreeView_GetParentHandle($hTreeView, $hItem)
If $hParent Then _SetParentItemsUnchecked($hTreeView, $hParent)
_GUICtrlTreeView_SetChecked($hTreeView, $hItem, False)
EndFunc