1

I've got a programatically created TableLayoutPanel, with each of its cells containing a Panel. Each Panel has a custom Label. (The Labels' Enabled property is set to false; not sure if that makes a difference.) I'd like to display the text of the Label whenever the user hovers over it with the mouse.

From what I've read, a ToolTip is a good way to do this, but I haven't been able to get it to work.

The TableLayoutPanel is name "tlp" for short and is a member of the form for easier access (likewise with the ToolTip, which is name "toolTip").

For now I'm just trying to get any kind of text. I'll replace my string here with the Label's text once I can get it to work.

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));
}

Neither of my attempts to display the ToolTip have been successful. Am I doing something wrong/is there a better method for doing what I'm trying to accomplish?

EDIT: I've attempted to add the toolTip to each Panel but still nothing is happening

// 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);
    }
}
Nick08
  • 157
  • 1
  • 2
  • 10
  • *"The `Label`s' `Enabled` property is set to `false`; not sure if that makes a difference"* - it does make a difference. Tooltips aren't shown for disabled controls. You could use [workarounds](http://stackoverflow.com/q/7887817/1997232) however. – Sinatr Aug 19 '16 at 14:13
  • Try setting panel's tooltip instead without event handler. If you move mouse over panel (but not yet over label) you will see it. – Sinatr Aug 19 '16 at 14:19
  • Didn't seem to work either (see edited code). – Nick08 Aug 19 '16 at 14:50
  • Why are labels disabled? Why not simply enable them and assign tooltip to labels? – Reza Aghaei Aug 19 '16 at 19:31

1 Answers1

2

This answer is based on code presented in the answer to: 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

It uses the TableLayoutPanelCellPosition computed by the referenced code to obtain the Control at that position (if any) and display its Text property as a ToolTip on the TableLayoutPanel.MouseHover event.

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);
    }
}

Edit:

I missed that the TLP is populated with controls with their Dock property set to DockStyle.Fill`. Such controls place placed in the TLP will receive the Mouse Events instead of the TLP. So as fix, add this method.

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);
    }
}

Then wireup the each Panel and Label grouping like this:

this.panel4.MouseHover += new System.EventHandler(this.showtip);
this.label4.MouseHover += new System.EventHandler(this.showtip);
TnTinMn
  • 11,522
  • 3
  • 18
  • 39
  • I've added the code mentioned and also this line under the TableLayoutPanel declaration "tlp.MouseHover += new EventHandler(tlp_MouseHover);" But now it's not even registering that the mouse is over the table. Did I assign this incorrectly? – Nick08 Aug 19 '16 at 17:43
  • Also, c would probably need to be tableLayoutPanel1.GetControlFromPosition(pos.Column, pos.Row).Controls[0]; since I want the text from the Label inside the Panel and not the Panel itself. But assuming I can fire the event, that is an easy fix – Nick08 Aug 19 '16 at 17:59
  • @NickV987, I missed that you filled the TableLayoutPanel with `Panel` controls set with a `DockStyle.Fill`. This slightly complicates the wiring of events. Since the controls above the TableLayoutPanel will be intercepting and processing the mouse events. I will post an update in a few minutes. – TnTinMn Aug 19 '16 at 18:15
  • I actually was able to get it by just linking the event to the Panels and taking it out from the TLP and Lables, fyi – Nick08 Aug 22 '16 at 12:33