【问题标题】:Show text when hovering over cell in TableLayoutPanel - C#将鼠标悬停在 TableLayoutPanel 中的单元格上时显示文本 - C#
【发布时间】:2016-08-20 02:25:34
【问题描述】:

我有一个以编程方式创建的 TableLayoutPanel,它的每个单元格都包含一个面板。每个面板都有一个自定义标签。 (Labels 的 Enabled 属性设置为 false;不确定这是否会有所不同。)我想在用户将鼠标悬停在 Label 上时显示其文本。

根据我的阅读,工具提示是实现此目的的好方法,但我无法让它发挥作用。

TableLayoutPanel 简称为“tlp”,是表单的成员,便于访问(与 ToolTip 一样,名称为“toolTip”)。

现在我只是想获取任何类型的文本。一旦我可以让它工作,我将在这里用标签的文本替换我的字符串。

private void hoverOverSpace(object sender, EventArgs e)
{
    int row = tlp.GetRow((Panel)sender);
    int col = tlp.GetColumn((Panel)sender);

    toolTip.Show("Does this work?", tlp.GetControlFromPosition(col, row).Controls[0]);
    //toolTip.Show("Does this work?", tlp.GetControlFromPosition(col, row));
}

我尝试显示工具提示都没有成功。我做错了什么/有没有更好的方法来完成我想要完成的事情?

编辑:我尝试将工具提示添加到每个面板,但仍然没有发生任何事情

// Add Panels to TableLayoutPanel
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
        // Create new Panel
        Panel space = new Panel()
       {
            Size = new Size(45, 45),
            Dock = DockStyle.Fill,
            Margin = new Padding(0)
        };

        space.MouseClick += new MouseEventHandler(clickOnSpace);

        CustomLabel info = new CustomLabel(false, 0, Color.White);      // Create new CustomLabel
        space.Controls.Add(info);   // Add CustomLabel to Panel
        tlp.Controls.Add(space, j, i);      // Add Panel to TableLayoutPanel

        toolTip = new ToolTip();
        toolTip.SetToolTip(space, info.Text);
    }
}

【问题讨论】:

  • Labels'Enabled 属性设置为 false;不确定这是否会有所作为” - 它确实有所作为。不显示禁用控件的工具提示。不过你可以使用workarounds
  • 尝试在没有事件处理程序的情况下设置面板的工具提示。如果您将鼠标移到面板上(但还没有移到标签上),您会看到它。
  • 似乎也不起作用(参见编辑后的代码)。
  • 为什么标签被禁用?为什么不简单地启用它们并将工具提示分配给标签?

标签: c# winforms tooltip tablelayoutpanel


【解决方案1】:

此答案基于以下答案中提供的代码:tablelayoutPanel get cell location from mouse over, by: Aland Li Microsoft CSS

    #region GetPosition
    // Modified from answer to: tablelayoutPanel get cell location from mouse over
    // By:  Aland Li Microsoft CSS
    // https://social.msdn.microsoft.com/Forums/windows/en-US/9bb6f42e-046d-42a0-8c83-febb1dcf98a7/tablelayoutpanel-get-cell-location-from-mouse-over?forum=winforms

//The method to get the position of the cell under the mouse.
private TableLayoutPanelCellPosition GetCellPosition(TableLayoutPanel panel, Point p)
{

    //Cell position
    TableLayoutPanelCellPosition pos = new TableLayoutPanelCellPosition(0, 0);
    //Panel size.
    Size size = panel.Size;
    //average cell size.
    SizeF cellAutoSize = new SizeF(size.Width / panel.ColumnCount, size.Height / panel.RowCount);

    //Get the cell row.
    //y coordinate
    float y = 0;
    for (int i = 0; i < panel.RowCount; i++)
    {
        //Calculate the summary of the row heights.
        SizeType type = panel.RowStyles[i].SizeType;
        float height = panel.RowStyles[i].Height;
        switch (type)
        {
            case SizeType.Absolute:
                y += height;
                break;
            case SizeType.Percent:
                y += height / 100 * size.Height;
                break;
            case SizeType.AutoSize:
                y += cellAutoSize.Height;
                break;
        }
        //Check the mouse position to decide if the cell is in current row.
        if ((int)y > p.Y)
        {
            pos.Row = i;
            break;
        }
    }

    //Get the cell column.
    //x coordinate
    float x = 0;
    for (int i = 0; i < panel.ColumnCount; i++)
    {
        //Calculate the summary of the row widths.
        SizeType type = panel.ColumnStyles[i].SizeType;
        float width = panel.ColumnStyles[i].Width;
        switch (type)
        {
            case SizeType.Absolute:
                x += width;
                break;
            case SizeType.Percent:
                x += width / 100 * size.Width;
                break;
            case SizeType.AutoSize:
                x += cellAutoSize.Width;
                break;
        }
        //Check the mouse position to decide if the cell is in current column.
        if ((int)x > p.X)
        {
            pos.Column = i;
            break;
        }
    }

    //return the mouse position.
    return pos;
}
#endregion

它使用引用代码计算的TableLayoutPanelCellPosition 来获取该位置的Control(如果有),并在TableLayoutPanel.MouseHover 事件上将其Text 属性显示为ToolTip

private void tableLayoutPanel1_MouseHover(object sender, EventArgs e)
{
    Point pt = tableLayoutPanel1.PointToClient(Control.MousePosition);
    TableLayoutPanelCellPosition pos = GetCellPosition(tableLayoutPanel1, pt);
    Control c = tableLayoutPanel1.GetControlFromPosition(pos.Column, pos.Row);
    if (c != null)
    {
        toolTip1.Show(c.Text, tableLayoutPanel1, pt, 500);
    }
}

编辑:

我错过了 TLP 填充了控件,其 Dock 属性设置为 DockStyle.Fill`。放置在 TLP 中的此类控件将接收鼠标事件而不是 TLP。所以作为修复,添加这个方法。

private void showtip(object sender, EventArgs e)
{
    Point pt = tableLayoutPanel1.PointToClient(Control.MousePosition);
    TableLayoutPanelCellPosition pos = GetCellPosition(tableLayoutPanel1, pt);
    Control c = tableLayoutPanel1.GetControlFromPosition(pos.Column, pos.Row);
    if (c != null && c.Controls.Count > 0)
    {
        toolTip1.Show(c.Controls[0].Text, tableLayoutPanel1, pt, 500);
    }
}

然后像这样连接每个PanelLabel 分组:

this.panel4.MouseHover += new System.EventHandler(this.showtip);
this.label4.MouseHover += new System.EventHandler(this.showtip);

【讨论】:

  • 我已经在 TableLayoutPanel 声明“tlp.MouseHover += new EventHandler(tlp_MouseHover);”下添加了提到的代码和这一行但是现在它甚至没有记录鼠标在桌子上。我分配错了吗?
  • 另外,c 可能需要为 tableLayoutPanel1.GetControlFromPosition(pos.Column, pos.Row).Controls[0];因为我想要面板内标签中的文本,而不是面板本身。但是假设我可以触发该事件,那很容易解决
  • @NickV987,我错过了你用Panel 控件集填充了TableLayoutPanel,并设置了DockStyle.Fill。这会使事件的连接稍微复杂化。由于 TableLayoutPanel 上方的控件会拦截和处理鼠标事件。我会在几分钟后发布更新。
  • 实际上,我只需将事件链接到小组并将其从 TLP 和标签中取出,就可以得到它,仅供参考
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
相关资源
最近更新 更多