2014-05-19 1 views
2

Microsoft Access에서 Microsoft TreeView Control 6.0을 사용하고 있습니다. 회색 노드가없는 상태로 보이지만 모든 자식 노드가 아니라 일부 노드가 검사됨을 나타냅니다.Microsoft TreeView Control 6.0 (MSComctlLib.TreeCtrl.2)에서 tri-state 확인란을 시뮬레이션 할 수 있습니까?

나는 자신의 이미지를 사용하여 체크 상자를 시뮬레이트했지만,이 경우 실제 체크 박스를 제거해야하거나 각 항목에 대해 두 개의 체크 박스가있는 것처럼 보입니다. 체크 박스가 없으므로 이미지 클릭을 처리하는 방법을 찾을 수 없습니다.

다른 언어/사용에서이 컨트롤에 대해 같은 종류의 질문을하는 사람들이 많지만 Microsoft Access 솔루션을 찾을 수 없습니다.

사용할 수있는 다른 것이 있으면 3 단계 체크 박스가있는 계층 구조가있는 다른 컨트롤로 이동해도 좋을 것입니다.

답변

2

약간의 연구와 2 시간 분량의 코딩을 거친 후 직접 솔루션을 작성할 수있었습니다.

ImageList를 추가하고이를 TreeView에 연결하고 각 세 가지 상태에 대한 체크 상자 이미지를 추가해야했습니다. Google 이미지 검색으로 시간이 절약되었습니다 :).

'Enumeration for simulated tri-state checkboxes, matching up to the TreeView's associated Image List's Index 
Private Enum CheckboxEnum 
    Unchecked = 1 
    Checked = 2 
    Partial = 3 
End Enum 

'--------------------------------------------------------------------------------------- 
' Procedure : objTreeView_MouseDown 
' Author : Matty Brown 
' Date  : 19/05/2014 
' Purpose : Because TreeView doesn't support tri-state checkboxes, these have to be simulated using images. 
'--------------------------------------------------------------------------------------- 
' 
Private Sub objTreeView_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As stdole.OLE_XPOS_PIXELS, ByVal y As stdole.OLE_YPOS_PIXELS) 
    Const CHECKBOX_WIDTH As Integer = 195 '195=13px 

    Dim objNode As Node 
    Set objNode = objTreeView.HitTest(x, y) 

    If objNode Is Nothing Then 
    'Miss 
    Else 
    'Find left side of node by moving left one pixel at a time until you fall off the node, then move one pixel to the right 
    Dim intX As stdole.OLE_XPOS_PIXELS 
    For intX = x To 0 Step -15 
     If Not objNode Is objTreeView.HitTest(intX, y) Then 
     If x <= intX + CHECKBOX_WIDTH Then 
      'User clicked on the checkbox 
      Select Case objNode.Image 
      Case CheckboxEnum.Unchecked: 
       objNode.Image = CheckboxEnum.Checked 
      Case Else: 
       objNode.Image = CheckboxEnum.Unchecked 
      End Select 

      'Recursively check child nodes 
      Call CheckTreeNodes(objTreeView, objNode, objNode.Image) 

      'Update parent node(s) 
      Call UpdateParentNodes(objTreeView, objNode) 
     Else 
      'User clicked outside of the checkbox 
      ' 
     End If 

     Exit For 
     End If 
    Next 
    End If 
End Sub 

'--------------------------------------------------------------------------------------- 
' Procedure : CheckTreeNodes 
' Author : Matty Brown 
' Date  : 16/05/2014 
' Purpose : Checks or unchecks all of the child nodes for the specified node 
'--------------------------------------------------------------------------------------- 
' 
Private Sub CheckTreeNodes(ByRef tv As TreeView, ByRef nodNode As Node, ByVal Value As CheckboxEnum) 
    Dim lngIndex As Long 

    'Cascade change to children 
    If nodNode.Children > 0 Then 
    lngIndex = nodNode.Child.Index 
    Call CheckTreeNodes(tv, tv.Nodes(lngIndex), Value) 

    Do While lngIndex <> nodNode.Child.LastSibling.Index 
     lngIndex = tv.Nodes(lngIndex).Next.Index 
     Call CheckTreeNodes(tv, tv.Nodes(lngIndex), Value) 
    Loop 
    End If 

    nodNode.Image = Value 
End Sub 

'--------------------------------------------------------------------------------------- 
' Procedure : CountChildNodes 
' Author : Matty Brown 
' Date  : 19/05/2014 
' Purpose : Counts how many child nodes are checked or unchecked, so that a parent node can be set correctly 
'--------------------------------------------------------------------------------------- 
' 
Private Sub CountChildNodes(ByRef tv As TreeView, ByRef nodNode As Node, ByRef lngChecked As Long, ByRef lngUnchecked As Long) 
    Dim lngIndex As Long 

    'Check this node's children 
    If nodNode.Children > 0 Then 
    lngIndex = nodNode.Child.Index 
    Call CountChildNodes(tv, tv.Nodes(lngIndex), lngChecked, lngUnchecked) 

    Do While lngIndex <> nodNode.Child.LastSibling.Index 
     lngIndex = tv.Nodes(lngIndex).Next.Index 
     Call CountChildNodes(tv, tv.Nodes(lngIndex), lngChecked, lngUnchecked) 
    Loop 
    Else 
    'Update totals 
    Select Case nodNode.Image 
     Case CheckboxEnum.Checked: 
     lngChecked = lngChecked + 1 
     Case CheckboxEnum.Unchecked: 
     lngUnchecked = lngUnchecked + 1 
    End Select 
    End If 
End Sub 


'--------------------------------------------------------------------------------------- 
' Procedure : UpdateParentNodes 
' Author : Matty Brown 
' Date  : 19/05/2014 
' Purpose : Steps through parent nodes, updating them according to how many checked/unchecked child nodes they have 
'--------------------------------------------------------------------------------------- 
' 
Private Sub UpdateParentNodes(ByRef tv As TreeView, ByRef nodNode As Node) 
    Dim lngIndex As Long 
    Dim nodParent As Node 
    Dim lngChecked As Long, lngUnchecked As Long 

    'If this node has no parents, there's nothing to update 
    If nodNode.Parent Is Nothing Then Exit Sub 
    Set nodParent = nodNode 

    Do While Not nodParent.Parent Is Nothing 
    Set nodParent = nodParent.Parent 

    'Reset counters 
    lngUnchecked = 0 
    lngChecked = 0 

    'Count children 
    Call CountChildNodes(tv, nodParent, lngChecked, lngUnchecked) 

    'Update parent nodes 
    If lngUnchecked = 0 And lngChecked > 0 Then 
     nodParent.Image = CheckboxEnum.Checked 
    ElseIf lngUnchecked > 0 And lngChecked > 0 Then 
     nodParent.Image = CheckboxEnum.Partial 
    Else 
     nodParent.Image = CheckboxEnum.Unchecked 
    End If 
    Loop 
End Sub 
관련 문제