C# 在 ToolStripItem 上显示 MetroFramework 工具提示

C# Showing MetroFramework ToolTip on ToolStripItem

我正在尝试使用 C# 的 MetroFramework 并在悬停 ToolStripItem 时显示漂亮的工具提示,而不是提供的 basic/regular 工具提示。

但是,我无法“按项目”显示它,因为 ToolStripItem 只有“所有者”控件 属性,它将在工具栏的所有项目中显示它。

示例:

private void toolStripButton1_MouseHover(object sender, EventArgs e)
{
   var tooltip = new MetroFramework.Components.MetroToolTip();

   ToolStripItem tsi = (ToolStripItem)sender;

   tooltip.SetToolTip(tsi.Owner, "testing the tooltips");
}

有人对此有解决方案吗?还是不编辑 MetroFramework 库就不可能?

非常感谢您的意见。

source code of this component, its derived from the System.Windows.Forms.ToolTip的基础上,我们可以用同样的方式来处理这个需求。

首先,您只需要一个表单中的 MetroToolTip 实例。要么使用设计器删除一个实例,要么在代码中创建一个实例并在关闭表单时将其处理掉。

要使其适用于每个项目:

  • 在设计时,设置 ToolStrip / MenuStrip / ContextMenuStrip / StatusStrip 项的 ToolTipText 属性。

  • 在构造函数或Form.Load事件中,通过递归方式获取ToolStripItem对象,订阅ClickMouseHoverMouseLeave 个事件。此外,还需要 ToolStripDropDownItem.DropDownOpening 事件。我们将处理它们以显示和隐藏工具提示。

例子

private readonly MetroToolTip mTt;

// ctor
public SomeForm()
{
    InitializeComponent();

    mTt = new MetroToolTip();

    // 3 strips just for demonstration.
    menuStrip1.ShowItemToolTips = false;
    toolStrip1.ShowItemToolTips = false;
    contextMenuStrip1.ShowItemToolTips = false;

    foreach (var item in GetAllToolStripItems(menuStrip1.Items)
        .Concat(GetAllToolStripItems(toolStrip1.Items))
        .Concat(GetAllToolStripItems(contextMenuStrip1.Items)))
    {
        if (!string.IsNullOrEmpty(item.ToolTipText))
        {
            item.AutoToolTip = false;
            item.Click += OnToolStripItemClick;
            item.MouseHover += OnToolStripItemMouseHover;
            item.MouseLeave += OnToolStripItemMouseLeave;
            if (item is ToolStripDropDownItem tsddi && tsddi.HasDropDown)
                tsddi.DropDownOpening += OnDropDownOpening;
        }
    }
}

// Clean up..
private void SomeForm_FormClosed(object sender, FormClosedEventArgs e) =>
    mTt.Dispose();

// Show the tooltip of the current item at a proper point.
private void OnToolStripItemMouseHover(object sender, EventArgs e)
{
    var s = sender as ToolStripItem;
    var p = Point.Add(Cursor.Position, new Size(0, Cursor.Size.Height));

    mTt.Show(s.ToolTipText, s.Owner, s.Owner.PointToClient(p));
}

// Hide the tooltip when the mouse pointer leaves the bounds of the current item.
private void OnToolStripItemMouseLeave(object sender, EventArgs e) =>
    mTt.Hide((sender as ToolStripItem).Owner);

// Hide the tooltip (if any) when a dropdown is about to open
// Otherwise it'll remain behind the dropdown window until the
// internal timer ticks.
private void OnDropDownOpening(object sender, EventArgs e) =>
    mTt.Hide((sender as ToolStripItem).Owner);

// For the ToolStrip control. To hide the tooltip right after clicking an item.
private void OnToolStripItemClick(object sender, EventArgs e) =>
    mTt.Hide((sender as ToolStripItem).Owner);

// A recursive method to get all the TSIs of any strip.
private static IEnumerable<ToolStripItem> GetAllToolStripItems(ToolStripItemCollection tsic)
{
    foreach (var tsi in tsic.Cast<ToolStripItem>())
    {
        yield return tsi;

        if (tsi is ToolStripDropDownItem tsddi && tsddi.HasDropDown)
            foreach (var ddi in GetAllToolStripItems(tsddi.DropDownItems))
                yield return ddi;
    }
}