VB.NET ContextMenuStrip未显示在GDI+控件的实际位置

本文关键字:控件 位置 GDI+ NET ContextMenuStrip 显示 VB | 更新日期: 2023-09-27 18:26:06

我有一个节点图控件,它继承自ContainerControl,并在其中绘制了一个节点列表,节点不是从任何地方继承的,只是由一些方法和一些属性组成。

我需要能够右键单击一个节点,然后在该位置显示ContextMenuStrip。我可以做得很好,但问题的开始是节点图控制缩放内容的能力。

当控件缩小时,ContextMenuStrip会发生偏移。我应该处理好这一点,因为我能够正确地发现鼠标坐标是否在节点边界内,但由于某种原因,ContextMenuStrip没有显示在鼠标坐标处。

下面是一段视频来展示这个问题:https://youtu.be/QNqQnWSENN8

我很抱歉,但由于这些愚蠢的限制,我无法发布我的大部分代码,所以我会尝试提供与问题有关的内容。

因此,我目前对节点图的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)

这基本上就是我在自动取款机上的做法。

我尝试了几种方法:

  1. 从show方法中删除NodeContainer,并将位置转换为屏幕坐标,但这并没有奏效,至少我没有这样做。

  2. 我已经尝试将节点的位置和大小添加到e.location中,显然也不起作用。

希望你能帮忙,谢谢。

VB.NET ContextMenuStrip未显示在GDI+控件的实际位置

解决方案是为该方法提供原始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