【问题标题】:WinForms: ToolTips will not (re)appear after the initial mouse hoverWinForms:初始鼠标悬停后工具提示不会(重新)出现
【发布时间】:2014-09-19 13:30:30
【问题描述】:

我正在开发一个表单,它使用 SharpMap MapBox 将对象显示为世界地图上的点。目前,如果我用光标输入 MapBox (mapBox1) 并停在该点上,它会显示我想要的工具提示。但是,一旦我在 MapBox 内停止鼠标(不一定在点上)并在 MapBox 内移动鼠标,移动到该点将不会(重新)显示工具提示。但是,如果我离开 MapBox(例如,将光标移出窗口或移到菜单条之一上,或移到覆盖在地图上的按钮上),我可以让工具提示出现,但在我必须之前只有一次像以前一样移动光标。

是什么导致了这种行为,有什么简单的方法可以解决吗?

我尝试过使用 ToolTip.Hide(), ToolTip.Active = false(然后在我希望它显示时再次将其设置为 true)并在各个点刷新 MapBox。

相关代码:

ToolTip 是全局的,构造函数定义如下:

toolTip.InitialDelay = 1000;
toolTip.ReshowDelay = 750;
toolTip.ShowAlways = true;

然后我有两个鼠标事件处理程序,都绑定到 MapBox。 “obj”是自定义类的全局对象,包含经纬度点。

private void mapBox1_MouseHover(object sender, EventArgs e)
    {
        PointF pos = mapBox1.PointToClient(Cursor.Position);
        int screenToleranceX = 20, screenToleranceY = 20;
        PointF posLow = new PointF(pos.X - screenToleranceX, pos.Y - screenToleranceY);
        PointF posHigh = new PointF(pos.X + screenToleranceX, pos.Y + screenToleranceY);
        GeoAPI.Geometries.Coordinate objLoc = new GeoAPI.Geometries.Coordinate(obj.longitude, obj.latitude);
        PointF objPoint = mapBox1.Map.WorldToImage(objLoc);
        if (posLow.X <= objPoint.X && objPoint.X <= posHigh.X && posLow.Y <= objPoint.Y && objPoint.Y <= posHigh.Y)
        {
            toolTip.Active = true;
            toolTip.Show(obj.Name, mapBox1, mapBox1.PointToClient(Cursor.Position));
        }
    }

    private void mapBox1_MouseMove(GeoAPI.Geometries.Coordinate worldPos, MouseEventArgs imagePos)
    {
        PointF pos = mapBox1.PointToClient(Cursor.Position);
        int screenToleranceX = 20, screenToleranceY = 20;
        PointF posLow = new PointF(pos.X - screenToleranceX, pos.Y - screenToleranceY);
        PointF posHigh = new PointF(pos.X + screenToleranceX, pos.Y + screenToleranceY);
        GeoAPI.Geometries.Coordinate objLoc = new GeoAPI.Geometries.Coordinate(obj.longitude, obj.latitude);
        PointF objPoint = mapBox1.Map.WorldToImage(objLoc);
        if (toolTip.Active && (posLow.X > objPoint.X || objPoint.X > posHigh.X || posLow.Y > objPoint.Y || objPoint.Y > posHigh.Y))
        {
            toolTip.Active = false;
        }
    }

** 编辑 **

根据接受的答案,我有以下代码作为解决方案,希望根据需要进一步完善它。但是,这目前有效(使用外部声明的 bool,toolTipDisp,默认为 false):

private void mapBox1_MouseMove(GeoAPI.Geometries.Coordinate worldPos, MouseEventArgs imagePos)
    {
        PointF pos = mapBox1.PointToClient(Cursor.Position);
        int screenToleranceX = 20, screenToleranceY = 20;
        PointF posLow = new PointF(pos.X - screenToleranceX, pos.Y - screenToleranceY);
        PointF posHigh = new PointF(pos.X + screenToleranceX, pos.Y + screenToleranceY);
        GeoAPI.Geometries.Coordinate objLoc = new GeoAPI.Geometries.Coordinate(obj.longitude, obj.latitude);
        PointF objPoint = mapBox1.Map.WorldToImage(objLoc);
        if (posLow.X <= objPoint.X && objPoint.X <= posHigh.X && posLow.Y <= objPoint.Y && objPoint.Y <= posHigh.Y)
        {
            if (!toolTipDisp)
            {
                toolTip.Show(obj.Name, mapBox1, mapBox1.PointToClient(Cursor.Position));
                toolTipDisp = true;
            }
        }
        else
        {
            toolTip.Hide(mapBox1);
            toolTipDisp = false;
        }
    }

【问题讨论】:

  • 你有没有浏览过代码。我敢打赌它不起作用,因为如果toolTip.Active = false;你有一个问题,你有没有查看文档以查看触发事件的顺序,也许它总是 .Active =一直都是假的。如果你注释掉toolTip.Active = false;,你会得到预期的行为吗??
  • 哪个操作系统?我记得当我从 XP 切换到 7 时,工具提示出现了一些问题。最后我得到了像this 这样的东西。设置工具提示会更新它,但只有在工具提示发生变化时才这样做(否则它会丑陋地闪烁)。
  • @Sinatr:我正在运行 Windows 7、Visual Studio 2013、.NET 4
  • @DJKRAZE:每当我浏览它时,我发现只要光标停在正确的位置,它就会尝试显示工具提示,正如我所期望的那样。如果我不使用 toolTip.Active = false,或者尝试隐藏 ToolTip,它会一直存在,直到我将焦点从包含 MapBox 的表单上移开,这更不可取。一种可能性是让工具提示在几秒钟后过期,但我宁愿它持续存在,因为在未来,我可能会有不止一个点坐在那里,而且几个点可能很接近。
  • 我不知道MapBox 是如何实现的,但我们假设它是一个单一的控件。然后MouseHover只出现一次,以后再也不会出现(直到MouseLeave)。您最好的选择是仅使用 MouseMove 来显示/重新显示工具提示。这就是我之前告诉你的:在MouseMove 事件中为工具提示生成一个文本。如果文本与原来不同 - 显示工具提示(通过使用 ToolTip.Show 方法),否则什么也不做。在MouseLeave 中隐藏工具提示(通过使用ToolTip.Hide 方法)。

标签: c# winforms tooltip sharpmap


【解决方案1】:

试试这个(伪代码):

private string _previous;

private void mapBox1_MouseMove(GeoAPI.Geometries.Coordinate worldPos, MouseEventArgs imagePos)
{
    var text = ...; // generate tooltip text based on the new position
    if(text != _previous)
    {
        _previous = text;
        tooltip.Show(text, mapBox1, mapBox1.PointToClient(imagePos.Location)); 
    }
}

private void mapBox1_MouseLeave(object sender, EventArgs e)
{
    toolTip.Hide(mapBox1);
}

【讨论】:

  • 这很接近,但我无法将 MouseLeave 事件用于我的目的。但是,这确实让我想到了我想出的解决方案,因此我将其标记为答案,并将我的最终解决方案发布为编辑。通过仅使用 MouseMove 事件,并使用先前在 MouseHover 事件(和 else)中的条件,我能够在鼠标进入点的边界框时显示工具提示。但是,这会导致工具提示闪烁。通过使用布尔变量,在显示工具提示时设置为 true,在隐藏时设置为 false,消除闪烁。
猜你喜欢
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多