【问题标题】:Prevent Form from showing outside the working area防止表单显示在工作区域之外
【发布时间】:2021-08-06 07:04:19
【问题描述】:

我创建了一个自定义表单以将其显示为工具提示,但要在其上显示数据,当用户将鼠标悬停在按钮上并在鼠标离开时消失时,将显示该显示,一切正常,但我怎样才能防止表单显示在屏幕区域之外??

这是我用来显示表单的代码:

Info_Form tooltip = new Info_Form();
private void Button131_MouseHover(object sender, EventArgs e)
{
    Button b = (Button)sender;

    tooltip = new Info_Form();
    tooltip.Height = tooltip.Height + 30;
    tooltip.Location = new Point(
    b.Right,
    b.Top);

    tooltip.Show();
}

private void Button131_MouseLeave(object sender, EventArgs e)
{
    tooltip.Close();
}

【问题讨论】:

  • 使用Screen s = Screen.FromControl(c); 获取当前屏幕,然后在没有完全相交时使用Rectangle r = s.WorkingArea; 重新定位工具提示表单。
  • @Loathing,在我得到Rectangle 之后,如何将它应用到 shwon 表单的位置?

标签: c# winforms tooltip


【解决方案1】:

我建议:

  • 在 Program.cs 中声明您的工具提示表单
  • 添加静态方法来显示和隐藏它

当然你可以使用一个公开静态方法的专用类来处理你的工具提示表单

然后,您可以从应用程序中的任何位置访问您的工具提示表单,只需在鼠标指针进入或离开特定控件时调用 ShowToolTip()HideToolTip():此控件的边界(转换为屏幕坐标)用作参考定位工具提示。

在这里,我使用一种简化的方法来确定 ToolTip 应该显示在参考控件的右侧还是左侧以及顶部或底部:

  • 如果引用 Control 位于屏幕的左半边,那么 Form 的左边部分是:ToolTip.Left = [ref Control].Left
  • 否则,ToolTip.Left = [ref Control].Right - ToolTip-Width
  • 同样的逻辑适用于工具提示的顶部位置

如果需要,调整这个简单的计算以使用不同的逻辑定位您的工具提示表单。

▶ 无需处置 ToolTip 表单:当传递给 Application.Run() 的 Form 实例关闭时,它会自动处置。

注意:如果应用程序不是 DpiAware 并且显示应用程序窗口的屏幕被缩放,则与屏幕或窗口/窗体相关的任何测量都可能被虚拟化,因此您会收到 错误结果,任何计算都将被取消。

在此处查看注释:
Using SetWindowPos with multiple monitors

using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;

public static frmToolTip tooltip = null;

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    tooltip = new frmToolTip();
    Application.Run(new SomeForm());
}

public async static Task ShowToolTip(Control control, string title) {
    await Task.Delay(400);
    if (tooltip.Visible) return;

    Rectangle refBounds = control.RectangleToScreen(control.ClientRectangle);
    if (!refBounds.Contains(Cursor.Position)) {
        HideToolTip();
    }
    else {
        var screen = Screen.GetBounds(control);
        var leftPos = refBounds.Left <= screen.Width / 2 ? refBounds.Left : refBounds.Right - tooltip.Width;
        var topPos = refBounds.Top <= screen.Height / 2 ? refBounds.Bottom + 2: refBounds.Top - tooltip.Height - 2;
        tooltip.Location = new Point(leftPos, topPos);
        tooltip.Text = title;
        tooltip.Show(control.FindForm());
    }
}
public static void HideToolTip() => tooltip.Hide();

在任何窗体中,使用控件的MouseEnterMouseLeave 事件来显示/隐藏您的工具提示。

注意:我使用Task.Delay() 来延迟工具提示的显示,因此如果您将鼠标指针短暂移动到显示它的控件上,它不会显示。
它还验证 Form ToolTip 是否已经显示(您不能显示 Form 两次)或鼠标指针是否同时移动到引用 Control 的边界之外(在这种情况下 ToolTip 不显示)。

根据需要更改此行为。

  • ShowToolTip() 中,我传递了一个字符串,旨在用作工具提示的标题。这只是一个示例,表明您可以将任何其他参数传递给此方法(可能是类对象)以自定义方式设置 ToolTip 表单,具体取决于调用者的要求。
using System.Threading.Tasks;

public partial class SomeForm : Form
{
   // [...]

    private async void SomeControl_MouseEnter(object sender, EventArgs e)
    {
        await Program.ShowToolTip(sender as Control, "Some Title Text");
    }

    private void SomeControl_MouseLeave(object sender, EventArgs e)
    {
        Program.HideToolTip();
    }
}

【讨论】:

  • 谢谢,这比我做的好很多,但是现在我在屏幕的顶部和底部遇到了同样的问题。
  • 啊,当然。好吧,这是相同的逻辑:如果显示工具提示的控件位于屏幕的中间/顶部区域,则在其下方显示表单,否则...在其上方(除此之外)?您想在哪里显示工具提示? -- 当然,您可以使计算稍微复杂一些,并始终考虑 ToolTip 大小。万一 ToolTip 大小可以改变,否则就没用了。
  • 正确,我用这段代码来完成那个var TopPos = refBounds.Bottom &lt;= screen.Height / 2 ? refBounds.Bottom : refBounds.Top - frm_info.Height;
  • 非常感谢你的详细回答,你让我开心:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多