VB.NET ContextMenuStrip 未显示在 GDI+ 控件的实际位置
VB.NET ContextMenuStrip is not shown at actual location GDI+ control
我有一个继承自 ContainerControl 的节点图控件,并在其中绘制了一个节点列表,这些节点不是从任何地方继承的,而只是由一些方法和一些属性组成。
我需要能够右键单击一个节点,然后在该位置显示一个 ContextMenuStrip。我可以做的很好,但问题开始于节点图控件缩放内容的能力。
当控件放大或缩小时,ContextMenuStrip 发生偏移。我应该注意这一点,因为我能够正确地找出鼠标坐标是否在节点范围内,但由于某种原因,ContextMenuStrip 没有显示在鼠标坐标处。
这是一个展示问题的视频:
https://youtu.be/QNqQnWSENN8
非常抱歉,由于这些愚蠢的限制,我不能 post 我的大部分代码,所以我会尝试提供与问题相关的内容。
所以我目前在节点图的MouseDown事件上做的是:
Public Overrides Sub OnMouseDown(e As MouseEventArgs)
Dim selectedNode = From n As Node In NodeContainer.Nodes Where n.Rectangle.Contains(e.Location) Select n
If selectedNode.Count = 1 Then
If NodeContainer.SelectedNodes.Count < 2 Then : NodeContainer.SelectNodeContainer() : End If
NodeContainer.SelectNode(selectedNode.LastOrDefault(), False)
NodeContainer.NodeContextMenuStrip.Show(NodeContainer, e.Location) 'Show node cms
Else
NodeContainer.SelectNodeContainer()
NodeContainer.NodeContainerContextMenuStrip.Show(NodeContainer, e.Location) 'Show container cms
End If
End Sub
该方法给出了这个 MouseEventArgs 对象:
Dim ev As New MouseEventArgs(e.Button, e.Clicks, (e.X - AutoScrollPosition.X) / Zoom, (e.Y - AutoScrollPosition.Y) / Zoom, e.Delta)
这基本上就是我在 atm 上做的事情。
我尝试了一些方法:
从 show 方法中删除 NodeContainer 并将位置转换为屏幕坐标,但这没有用,至少不是我这样做的方式。
我试过将节点的位置和大小添加到e.Location,显然也没有用。
希望能帮到你,谢谢。
解决方案是为方法提供原始 MouseEventArgs 对象,然后在方法中创建新的 MouseEventArgs 对象。
所以(前后带*的行已被插入或更改):
Public Overrides Sub OnMouseDown(e As MouseEventArgs)
*Dim ev As New MouseEventArgs(e.Button, e.Clicks, (e.X - AutoScrollPosition.X) / Zoom, (e.Y - AutoScrollPosition.Y) / Zoom, e.Delta)*
Dim selectedNode = From n As Node In NodeContainer.Nodes Where n.Rectangle.Contains(*ev.Location*) Select n
If selectedNode.Count = 1 Then
If NodeContainer.SelectedNodes.Count < 2 Then : NodeContainer.SelectNodeContainer() : End If
NodeContainer.SelectNode(selectedNode.LastOrDefault(), False)
NodeContainer.NodeContextMenuStrip.Show(NodeContainer, e.Location) 'Show node cms
Else
NodeContainer.SelectNodeContainer()
NodeContainer.NodeContainerContextMenuStrip.Show(NodeContainer, e.Location) 'Show container cms
End If
End Sub
我有一个继承自 ContainerControl 的节点图控件,并在其中绘制了一个节点列表,这些节点不是从任何地方继承的,而只是由一些方法和一些属性组成。
我需要能够右键单击一个节点,然后在该位置显示一个 ContextMenuStrip。我可以做的很好,但问题开始于节点图控件缩放内容的能力。
当控件放大或缩小时,ContextMenuStrip 发生偏移。我应该注意这一点,因为我能够正确地找出鼠标坐标是否在节点范围内,但由于某种原因,ContextMenuStrip 没有显示在鼠标坐标处。
这是一个展示问题的视频: https://youtu.be/QNqQnWSENN8
非常抱歉,由于这些愚蠢的限制,我不能 post 我的大部分代码,所以我会尝试提供与问题相关的内容。
所以我目前在节点图的MouseDown事件上做的是:
Public Overrides Sub OnMouseDown(e As MouseEventArgs)
Dim selectedNode = From n As Node In NodeContainer.Nodes Where n.Rectangle.Contains(e.Location) Select n
If selectedNode.Count = 1 Then
If NodeContainer.SelectedNodes.Count < 2 Then : NodeContainer.SelectNodeContainer() : End If
NodeContainer.SelectNode(selectedNode.LastOrDefault(), False)
NodeContainer.NodeContextMenuStrip.Show(NodeContainer, e.Location) 'Show node cms
Else
NodeContainer.SelectNodeContainer()
NodeContainer.NodeContainerContextMenuStrip.Show(NodeContainer, e.Location) 'Show container cms
End If
End Sub
该方法给出了这个 MouseEventArgs 对象:
Dim ev As New MouseEventArgs(e.Button, e.Clicks, (e.X - AutoScrollPosition.X) / Zoom, (e.Y - AutoScrollPosition.Y) / Zoom, e.Delta)
这基本上就是我在 atm 上做的事情。
我尝试了一些方法:
从 show 方法中删除 NodeContainer 并将位置转换为屏幕坐标,但这没有用,至少不是我这样做的方式。
我试过将节点的位置和大小添加到e.Location,显然也没有用。
希望能帮到你,谢谢。
解决方案是为方法提供原始 MouseEventArgs 对象,然后在方法中创建新的 MouseEventArgs 对象。
所以(前后带*的行已被插入或更改):
Public Overrides Sub OnMouseDown(e As MouseEventArgs)
*Dim ev As New MouseEventArgs(e.Button, e.Clicks, (e.X - AutoScrollPosition.X) / Zoom, (e.Y - AutoScrollPosition.Y) / Zoom, e.Delta)*
Dim selectedNode = From n As Node In NodeContainer.Nodes Where n.Rectangle.Contains(*ev.Location*) Select n
If selectedNode.Count = 1 Then
If NodeContainer.SelectedNodes.Count < 2 Then : NodeContainer.SelectNodeContainer() : End If
NodeContainer.SelectNode(selectedNode.LastOrDefault(), False)
NodeContainer.NodeContextMenuStrip.Show(NodeContainer, e.Location) 'Show node cms
Else
NodeContainer.SelectNodeContainer()
NodeContainer.NodeContainerContextMenuStrip.Show(NodeContainer, e.Location) 'Show container cms
End If
End Sub