I have an old WinForms application with a normal TreeView, where I need to show customized tooltips for individual nodes.
I am using a ToolTip component (OwnerDraw=true and IsBalloon=false), and I show the tooltip programmatically with ToolTip.Show() from the MouseMove event of the TreeView. The Popup event handler (correctly) calculates and sets the tooltip size, and the Draw event handler (correctly) draws the tooltip.
My problem is that the Popup event does not fire - only the Draw event, resulting in that the displayed tooltip is much too small for the contents (I need to use a large fixed-width font: Consolas, 12).
I have already asked a question about this, thinking that I was doing something wrong, but I have now found that this works fine (for me) with .NET 8, but not with .NET Framework. I have tested .NET Framework 4.8 (which is what I have to use), 4.7.2, and 4.6.2 - the Popup event is not triggered with any of them.
From the .NET documentation on the ToolTip.Popup event (this is for 4.6.2, but it is the same for the others):
The Popup event is raised whenever a ToolTip is displayed, either through an explicit call to one of the Show methods or when the ToolTip class implicitly displays a ToolTip.
That part about it being raised for "an explicit call to one of the Show methods" does not seem to be true, or am I missing something?
I am not allowed to show my source code, but in his answer to my previous question, @Olivier Jacot-Descombes included the following code, which is very much like how I am doing it, and this is also the code I have been using for my tests since then:
public partial class FormTreeNodeToolTip : Form
{
private static readonly Font _font = new Font("Consolas", 16, FontStyle.Regular);
private TreeNode _currentNode;
public FormTreeNodeToolTip()
{
InitializeComponent();
treeView1.Nodes.Add(new TreeNode("First node"));
treeView1.Nodes.Add(new TreeNode("Second node with longer text"));
treeView1.Nodes.Add(new TreeNode("Third node"));
}
private void ToolTip1_Draw(object sender, DrawToolTipEventArgs e)
{
e.Graphics.Clear(Color.LightYellow);
e.Graphics.DrawString(e.ToolTipText, _font, Brushes.Blue, e.Bounds);
}
private void TreeView1_NodeMouseHover(object sender, TreeNodeMouseHoverEventArgs e)
{
_currentNode = e.Node;
Point cursor = treeView1.PointToClient(Cursor.Position);
toolTip1.Show(e.Node.Text, treeView1, cursor.X + 20, cursor.Y + 20, 800);
}
private void ToolTip1_Popup(object sender, PopupEventArgs e)
{
e.ToolTipSize = TextRenderer.MeasureText(_currentNode.Text, _font);
}
private void TreeView1_MouseMove(object sender, MouseEventArgs e)
{
if (treeView1.GetNodeAt(e.Location) != _currentNode) {
_currentNode = null;
toolTip1.Hide(treeView1);
}
}
private void TreeView1_MouseLeave(object sender, EventArgs e)
{
toolTip1.Hide(treeView1);
}
}
I should add that I have tried using different events for showing the tooltip, setting ToolTip.Active to false and back to true when hiding/showing a tooltip, actively removing the "old" tooltip with ToolTip.SetToolTip() and ToolTip.RemoveAll(), and similar. Nothing I do makes any difference - the Popup event still does not fire.
So, is this a bug in .NET Framework, or am I missing something? What (if anything) can I do to make this work?
UPDATE 1:
Adding the form's designer code on request:
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.treeView1 = new System.Windows.Forms.TreeView();
this.SuspendLayout();
//
// toolTip1
//
this.toolTip1.OwnerDraw = true;
this.toolTip1.Draw += new System.Windows.Forms.DrawToolTipEventHandler(this.ToolTip1_Draw);
this.toolTip1.Popup += new System.Windows.Forms.PopupEventHandler(this.ToolTip1_Popup);
//
// treeView1
//
this.treeView1.Location = new System.Drawing.Point(0, 0);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(306, 231);
this.treeView1.TabIndex = 0;
this.treeView1.NodeMouseHover += new System.Windows.Forms.TreeNodeMouseHoverEventHandler(this.TreeView1_NodeMouseHover);
this.treeView1.MouseLeave += new System.EventHandler(this.TreeView1_MouseLeave);
this.treeView1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.TreeView1_MouseMove);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(710, 304);
this.Controls.Add(this.treeView1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
UPDATE 2:
Added a few lines to the constructor in the example to add a couple of nodes in the TreeView. I did not think to mention that this simple example just shows the node's caption as tooltip, so the longer the caption string, the more obvious it becomes that the tooltip has an incorrect size.
Clarification:
This is not how the actual application works. There, the multi-line tooltip text for a node is decided based on other stuff, and needs to be assembled at the moment it is displayed.
It must also be displayed with a fixed-width font (we use Consolas 12, the example uses Consolas 16 to make the problem more visible even with short tooltips).

InitializeComponent()method to the question now - it is not that big.ToolTip1_Popup()method is called. (Note that I am running it on .NET 4.8 but using an SDK-style project, not a legacy-style project.)Form1_MouseHoverto show the tooltip?