当我选中某个节点的时候,在nodeCheck事件中我判断该节点是否满足选中的条件,如果不满足,那么不让他选中,现在我在事件中设置node.checked=false不管用,哪位知道怎么能行?
另外,单击复选框的时候,按下鼠标后不抬起鼠标键,然后把鼠标拖到别的地方再抬起,这时候仍然复选,但是不触发NodeCheck事件,这该怎么办?

解决方案 »

  1.   

    Mark下,一直沒有試過,等下來試
      

  2.   

    明天試,老是要自己去檢查樹,真是麻煩你自己先看看http://vbnet.mvps.org/index.html?code/comctl/lvledgerrows.htm遮裡面
      

  3.   

    http://vbnet.mvps.org/index.html?code/comctl/lvledgerrows.htm
    和这个问题无关
      

  4.   

    给个思路Private moCheckedNode As Node
    Private Sub Form_Load()
        Dim oNode As Node
        With TreeView1
            .Nodes.Add , , "r1", "r1"
            .Nodes.Add , , "r2", "r2"
                .Nodes.Add "r2", tvwChild, "r3", "r3"
                .Nodes.Add "r2", tvwChild, "r4", "r4"
                    .Nodes.Add "r4", tvwChild, "r5", "r5"
                    .Nodes.Add "r4", tvwChild, "r6", "r6"
                        .Nodes.Add "r6", tvwChild, "r11", "r11"
                .Nodes.Add "r2", tvwChild, "r7", "r7"
                    .Nodes.Add "r7", tvwChild, "r10", "r10"
        
            .Nodes.Add , , "r8", "r8"
                Set oNode = .Nodes.Add("r8", tvwChild, "r9", "r9")
        End WithEnd SubPrivate Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node)
        Set moCheckedNode = Node
    End Sub
    Private Sub TreeView1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
        If Not moCheckedNode Is Nothing Then'触发过NodeCheck事件了
            '做要做的事情
            '比如说把moCheckedNode.Checked = False
            Set moCheckedNode = Nothing'清空对象继续等待
        End If
    End Sub
      

  5.   

    思路不错,肯定能实现,但是又要多一个模块级变量了,另外按空格键的时候也能触发NodeCheck事件,所以在MouseUp中并不能解决问题,难道再加上一个keyup事件处理?这样子程序代码是不是很难看?不知道通过子类截获消息行不行?对于第二个问题,是不是控件的bug?
      

  6.   

    子类处理是肯定可以的,但肯定写起来也很难看的,呵呵。来,再一个思路:
    Private moCheckedNode As Node
    Private mfPrevState As Boolean
    Private Sub Form_Load()
        Dim oNode As Node
        With TreeView1
            .Nodes.Add , , "r1", "r1"
            .Nodes.Add , , "r2", "r2"
                .Nodes.Add "r2", tvwChild, "r3", "r3"
                .Nodes.Add "r2", tvwChild, "r4", "r4"
                    .Nodes.Add "r4", tvwChild, "r5", "r5"
                    .Nodes.Add "r4", tvwChild, "r6", "r6"
                        .Nodes.Add "r6", tvwChild, "r11", "r11"
                .Nodes.Add "r2", tvwChild, "r7", "r7"
                    .Nodes.Add "r7", tvwChild, "r10", "r10"
        
            .Nodes.Add , , "r8", "r8"
                Set oNode = .Nodes.Add("r8", tvwChild, "r9", "r9")
        End With
    End SubPrivate Sub TreeView1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
        Set moCheckedNode = TreeView1.HitTest(x, y)'抓节点
        If moCheckedNode Is Nothing Then Exit Sub
        mfPrevState = moCheckedNode.Checked'存储老的状态
    End Sub
    Private Sub TreeView1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
        If Not moCheckedNode Is Nothing Then
            If moCheckedNode.Checked <> mfPrevState Then '状态改变过了,也就是点击过CheckBox了,也就相当于NodeCheck事件
                '做要做的事情
                '比如说把
                moCheckedNode.Checked = IIf(moCheckedNode.Text = "r2", True, False)
                Set moCheckedNode = Nothing '清空对象继续等待
            End If
        End If
    End Sub
      

  7.   

    你这样子只能处理鼠标,控制不了空格键改变checked属性,而且对第二个问题也没有很好的解决,因为鼠标可能拖出treeview再释放,总不能在form_mouseup中再捕获吧?而且如果鼠标拖出窗口再释放就没办法了
    个人认为还是在nodeCheck事件中解决为好
      

  8.   

    刚才试了一下,mouseup事件是可以捕获的,这样的话Private Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node)
        if 要取消选择 then
            Set moCheckedNode = Node
        end if
    End SubPrivate Sub TreeView1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
        If Not moCheckedNode Is Nothing Then'触发过NodeCheck事件了
            '做要做的事情
            moCheckedNode.Checked =not moCheckedNode.Checked 
            Set moCheckedNode = Nothing'清空对象继续等待
        End If
    End SubPrivate Sub TreeView1_keyUp()
        If Not moCheckedNode Is Nothing Then'触发过NodeCheck事件了
            '做要做的事情
            moCheckedNode.Checked =not moCheckedNode.Checked 
            Set moCheckedNode = Nothing'清空对象继续等待
        End If
    End Sub这样子就可以了但是对于第二个问题,因为不触发nodecheck事件,所以还是无法解决,因为在mousedown事件中并不能判断出用户是否点了复选框,也可能仅仅在节点上单击了一下,并没有复选,所以第二个问题还是无法解决,我觉得这是treeview控件的一个bug
      

  9.   

    对于第二个问题,我有如下思路:dim nod as nodePrivate Sub TreeView1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
        
        Set nod = TreeView1.HitTest(x, y)'抓节点
        if nod is nothing then exit sub
        mfPrevState = nod.Checked'存储老的状态
    End SubPrivate Sub TreeView1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)    dim nodtmp as node
        Set nodtmp = TreeView1.HitTest(x, y)'抓节点
        if nodtmp is nothing then exit sub
        If moCheckedNode Is Nothing Then Exit Sub 
        if nodtmp.key<>nod.key then   '鼠标移开了节点
            nod.checked=mfPrevState 
            exit sub
        end if    moCheckedNode.Checked =not moCheckedNode.Checked 
        Set moCheckedNode = Nothing'清空对象继续等待            
    End Sub
    共设置三个模块级变量,解决以上所有问题
      

  10.   

    对于第2问题,用我第2个思路应该可以解决吧在第2个思路后面再加上Private Sub TreeView1_KeyDown(KeyCode As Integer, Shift As Integer)
        Set moCheckedNode = TreeView1.SelectedItem
        If moCheckedNode Is Nothing Then Exit Sub
        mfPrevState = moCheckedNode.Checked
    End SubPrivate Sub TreeView1_KeyUp(KeyCode As Integer, Shift As Integer)
        If Not moCheckedNode Is Nothing Then '触发过NodeCheck事件了
            '做要做的事情
            moCheckedNode.Checked = False
            Set moCheckedNode = Nothing '清空对象继续等待
        End If
    End Sub