我正在使用一个Excel VBA应用程序,该应用程序包含两个树视图控件,这些控件包含在一个用户窗体中。两者之间的唯一区别是Treeview1具有两个级别的节点,Treeview2具有三个级别的节点。两种树视图都使用相同的事件处理程序:
BeforeLabelEdit
MouseDown
MouseMove
Nodeclick
OLEDragDrop
OLEDragOver
当用户在treeview1中单击鼠标节点时,事件序列为MouseDown,然后为Nodeclick。但是,对于Treeview2,当用户单击节点时,仅 Nodeclick事件被触发。经过一些测试,我发现如果为treeview2添加MouseUp事件处理程序,它将在Nodeclick事件之后触发。 看来MouseDown事件永远不会触发。
我想知道是否有人遇到过类似的问题。我可以对此进行编码,但是我真的很想了解为什么会这样。我假设我对事件触发器的排序方式不了解。
我正在使用MouseDown捕获鼠标和按钮选择,并使用Nodeclick标识所选节点。我最初使用 MouseDown事件处理程序以(1)捕获键/按钮选择和(2)使用HitTest函数捕获选定的节点。但是,hitTest不是 在另一台计算机上测试应用程序时捕获正确的节点。添加Nodeclick eventHandler似乎比尝试为之编写通用方法要容易 计算/转换不同计算机上的像素。
代码非常复杂,因此我只为每个树形视图包括了MouseDown和Nodeclick处理程序。
我正在运行Windows10版本1903和Office 365(16.0.12026.20344)64位。我知道,过去使用 在64位环境中使用Treeview控件,因此这可能相关吗?
任何想法都会受到赞赏。
谢谢!
'=============================================================
'===== Event Handlers for Treeview 1 =========================
'=============================================================
Private Sub TreeView_LineItem_MouseDown(ByVal Button As Integer,ByVal Shift As Integer,ByVal x As stdole.OLE_XPOS_PIXELS,ByVal y As stdole.OLE_YPOS_PIXELS)
gButton = Button
gShift = Shift
End Sub
Private Sub TreeView_LineItem_Nodeclick(ByVal Node As MSComctlLib.Node)
Set gSelectedNode = Node
If Not (gSelectedNode Is Nothing) Then
If gShift = 0 Then
If gButton = 1 Then 'Left Mouse
Call Node_Enter(ControlPanel.TreeView_LineItem,gNodeCollLineItems,gNodeGraphLineItems,gSelectedNode)
Set prevSelectedNodeclick = gSelectedNode
Set prevSelectedNodeControl = Nothing
Set prevSelectedNodeShift = Nothing
ControlPanel.TreeView_LineItem.Refresh
If ControlPanel.Visible = False Then
ControlPanel.Show vbModeless
End If
ElseIf gButton = 2 Then 'Right Mouse
'Custom node selected for deletion
If gCustomLineItemDelete = True And gNumCustomLineItems > 1 Then
Call DeleteCustomLineItemStep2(gSelectedNode,ControlPanel.TreeView_LineItem.Nodes)
Application.Goto Reference:=wb.Sheets(1).Range("A1"),Scroll:=True
gCustomLineItemDelete = False
ElseIf gCustomLineItemModify = True And gNumCustomLineItems > 1 Then
Call modifyCustomLineItemStep2(gSelectedNode,Scroll:=True
gCustomLineItemModify = False
'Delete menu line item selected
ElseIf gCustomLineItemDelete = False Or gNumCustomLineItems = 1 Then
If gNumCustomLineItems = 1 Then
MsgBox "There are no custom line items"
End If
For Each cb In CommandBars
If StrComp(cb.name,"LineItem") = 0 Then
cb.Delete
End If
Next
If gCustomLineItemDelete = True Then
GoTo endSub
End If
'Reset menu
Set PopBar = CommandBars.Add(name:="LineItem",Position:=msoBarPopup,MenuBar:=False,Temporary:=True)
Set Top_Menu = PopBar.Controls.Add(Type:=msoControlButton,before:=1,Temporary:=True)
With Top_Menu
.caption = "Clear LineItem Selections"
.Onaction = "ClearLineItemCollections"
End With
PopBar.ShowPopup
End If
End If
ElseIf gShift = 1 Then 'Shift
Call Node_Shift(ControlPanel.TreeView_LineItem,gSelectedNode)
Set prevSelectedNodeShift = gSelectedNode
Set prevSelectedNodeControl = Nothing
Set prevSelectedNodeclick = Nothing
ControlPanel.TreeView_LineItem.Refresh
ControlPanel.Show vbModeless
ElseIf gShift = 2 Then 'Cntl
Call Node_Control(ControlPanel.TreeView_LineItem,gSelectedNode)
Set prevSelectedNodeControl = gSelectedNode
Set prevSelectedNodeclick = Nothing
Set prevSelectedNodeShift = Nothing
ControlPanel.TreeView_LineItem.Refresh
ControlPanel.Show vbModeless
End If
End If
End Sub
'=============================================================
'===== Event Handlers for Treeview 2 =========================
'=============================================================
Private Sub TreeView_Segment_MouseDown(ByVal Button As Integer,ByVal y As stdole.OLE_YPOS_PIXELS)
gShift = Shift
gButton = Button
End Sub
Private Sub TreeView_Segment_Nodeclick(ByVal Node As MSComctlLib.Node)
set gSelectedNode = Node
gShift = Shift
gButton = Button
If Not (gSelectedNode Is Nothing) Then
If gShift = 0 Then
If gButton = 1 Then 'left mouse
Call Node_Enter(ControlPanel.TreeView_Segment,gNodeCollSegments,gNodeGraphSegments,gSelectedNode)
Set prevSelectedNodeclick = gSelectedNode
Set prevSelectedNodeControl = Nothing
Set prevSelectedNodeShift = Nothing
If ControlPanel.TreeView_Segment.SelectedItem <> gSelectedNode Then
ControlPanel.TreeView_Segment.SelectedItem = gSelectedNode
ControlPanel.TreeView_Segment.DropHighlight = gSelectedNode
End If
ControlPanel.TreeView_Segment.Refresh
ElseIf gButton = 2 Then 'Right Mouse
For Each cb In CommandBars
If StrComp(cb.name,"Segment") = 0 Then
cb.Delete
End If
Next
Set PopBar = CommandBars.Add(name:="Segment",Temporary:=True)
Set Top_Menu = PopBar.Controls.Add(Type:=msoControlButton,Temporary:=True)
With Top_Menu
.caption = "Clear Segment Selections"
.Onaction = "ClearSegmentCollections"
End With
PopBar.ShowPopup
End If
ElseIf gShift = 1 Then 'Shift
Call Node_Shift(ControlPanel.TreeView_Segment,gSelectedNode)
Set prevSelectedNodeShift = gSelectedNode
Set prevSelectedNodeControl = Nothing
Set prevSelectedNodeclick = Nothing
If ControlPanel.TreeView_Segment.SelectedItem <> gSelectedNode Then
ControlPanel.TreeView_Segment.DropHighlight = Nothing
End If
ControlPanel.TreeView_Segment.Refresh
ControlPanel.Show vbModeless
ElseIf gShift = 2 Then 'Cntl
Call Node_Control(ControlPanel.TreeView_Segment,gSelectedNode)
Set prevSelectedNodeControl = gSelectedNode
Set prevSelectedNodeclick = Nothing
Set prevSelectedNodeShift = Nothing
If ControlPanel.TreeView_Segment.SelectedItem <> gSelectedNode Then
ControlPanel.TreeView_Segment.SelectedItem = gSelectedNode
End If
ControlPanel.TreeView_Segment.Refresh
ControlPanel.Show vbModeless
End If
End If
endSub:
End Sub