后来发现nodecheck事件是不要做鼠标事件也可以也可以响应的,所以就只做了个checknode过程但是有很多bug,1. 点太快,程序就死掉了
2. 有时候选中上层的节点,下下层的孙子节点儿子节点没有选中
3. 有时候点一个爸爸节点,另外一个爸爸节点会变成这个节点,然后就乱七八糟了本来的树状图为
 root
    |______SBF
    |
    |______Region如果点击region,上面的SBF连节点名都变成Region了很奇怪的NodeCheck代码如下Private Sub tvReportFilter_NodeCheck(ByVal Node As Object)
    
 Dim currNodeIndex As Integer
    Dim IsChecked As Boolean
    Dim sNode As Node
    Dim pNode As Node
    Dim allSiblingIsChecked As Boolean    currNodeIndex = Node.Index
    IsChecked = Node.Checked
If currNodeIndex = 1 Then 'If current node is root, go over the whole tree
  For i = 0 To tvReportFilter.Nodes.count - 1
     tvReportFilter.Nodes(i + currNodeIndex).Checked = IsChecked
  Next i
Else
    If Node.Children > 0 Then
        For i = 1 To Node.Children 'or go over the subtree of current node
        tvReportFilter.Nodes(i + currNodeIndex).Checked = IsChecked
        Next i
    End If
    
    Set sNode = Node.FirstSibling
    Set pNode = Node.Parent
    siblingIsChecked = True
    If pNode.Children > 1 Then
    
        Do While Not IsNull(sNode) And sNode <> Node.LastSibling
                
            allSiblingIsChecked = allSiblingIsChecked And sNode.Checked
            sNode = sNode.Next
        Loop
        
        
        
    ElseIf pNode.Children = 1 Then
        allSiblingIsChecked = allSiblingIsChecked And Node.Checked
    End If
    
    
    pNode.Checked = allSiblingIsChecked
        
    Set sNode = Nothing
    Set pNode = Nothing        
End If
End Sub代码目的是让如果点了跟节点就把所有的节点都选中,如果不是根节点就把它下面的子节点都选中,然后扫描兄弟节点,如果兄弟节点和当前节点都是选中状态了,再把父亲节点改成选中状态,但是不知道为啥运行效果和预想的不同麻烦高手帮忙看看哪儿出问题了

解决方案 »

  1.   

    那么请问如何改变这段程序的performance我的用户可不管,点快点应该是注定会发生的事情
      

  2.   

    tryPrivate blnRun As BooleanPrivate Sub Form_Load()
        blnRun = False
    End SubPrivate Sub tvReportFilter_NodeCheck(ByVal Node As Object)
        
        Dim currNodeIndex As Integer
        Dim IsChecked As Boolean
        Dim sNode As Node
        Dim pNode As Node
        Dim allSiblingIsChecked As Boolean
        
        If blnRun Then Exit Sub  '判断
        blnRun = True  '锁定
            
        currNodeIndex = Node.Index
        IsChecked = Node.Checked
        
        If currNodeIndex = 1 Then 'If current node is root, go over the whole tree
            For i = 0 To tvReportFilter.Nodes.Count - 1
                tvReportFilter.Nodes(i + currNodeIndex).Checked = IsChecked
            Next i
        Else
            If Node.Children > 0 Then
                For i = 1 To Node.Children 'or go over the subtree of current node
                    tvReportFilter.Nodes(i + currNodeIndex).Checked = IsChecked
                Next i
            End If
            
            Set sNode = Node.FirstSibling
            Set pNode = Node.Parent
            siblingIsChecked = True
            
            If pNode.Children > 1 Then
                Do While Not IsNull(sNode) And sNode <> Node.LastSibling
                    allSiblingIsChecked = allSiblingIsChecked And sNode.Checked
                    sNode = sNode.Next
                Loop
            ElseIf pNode.Children = 1 Then
                allSiblingIsChecked = allSiblingIsChecked And Node.Checked
            End If
            
            pNode.Checked = allSiblingIsChecked
            
            Set sNode = Nothing
            Set pNode = Nothing
        End If
        
        blnRun = False  '恢复
    End Sub
      

  3.   

    哦,好的,我再尝试下,还有为啥我初始化的时候都是正确的我点了个节点,region,另外一个节点SBF会变成region,虽然它下面的子节点没变错但是我点region,SBF下的子节点也会被选中
      

  4.   

    我用了你的代码,可还是不行,我知道你代码的用途就是说当一个sub还没运行结束就就算触发也不运行但是这也有一些问题,我觉得吧,如果现在一个checkbox已经触发了nodecheck,又点了一个checkbox,这时候触发被停止,那这个checkbox的事件什么时候可以再次触发,要不就满足不了需求了是不是需要让等待中的先sleep,然后再触发?
      

  5.   

    运行后我已经加恢复了    End If
        
        blnRun = False  '恢复
    End Sub
      

  6.   

    我不知道触发机制是怎么样的,应该是点了checkbox就触发,可是触发的时候如果blnRun是true的时候那么就直接exit sub了,那这个checkbox操作怎么再次触发我现在想法是不是这样做一个wait的队列,如果blnRun是true的时候,就把这些节点都进队列,然后都进入listen状态,如果blnRun是false了就按照顺序从wait队列里拿一个node出来调用触发过程,这样是不是应该能解决现在的问题?如果你有空可以帮我看下代码吗,jhone99,我不知道我代码是不是正确
      

  7.   


    哦,是这样,就是说譬如我点了SBF节点,然后会触发下面的节点的nodecheck过程
    是这意思是吧,那如果这些触发被deny了,那么怎么再触发呢,我改了以后还是一样会死是不是我代码里有缺陷呢,如果有空还是要麻烦您帮我看下,不是很长,也不是很复杂
      

  8.   

    OK,我调下,然后我会把结果发上来,谢谢你的关注by the way, 你有看过我代码么,感觉有问题吗?
      

  9.   


    选父节点,则自动选择子节点,给一段经典的代码,记得好象是当年VB版的李洪根所出   Public Sub CheckChild(ByVal Node As MSComctlLib.Node, ByVal bCheck As Boolean, Optional ByVal bNext As Boolean = True, Optional ByVal bChild As Boolean = True)
        If Not Node Is Nothing Then
            Node.Checked = bCheck
            If Node.Children And bChild Then
                Call CheckChild(Node.Child, bCheck, True, True)        '对子节点
            End If
            If bNext Then
                Call CheckChild(Node.Next, bCheck, True, bChild)          '对同一层节点
            End If
           
        End IfEnd SubPrivate Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node)
        Call CheckChild(Node, Node.Checked, False, True)                    '处理子节点
    End Sub