.NET 4.8中Popup事件内设置ToolTip文本致程序崩溃
.NET 4.8 ToolTip Popup事件中调用SetToolTip导致崩溃的解决办法
问题重现
在.NET 4.8 WinForms项目中,尝试在ToolTip.Popup事件内动态设置控件的ToolTip文本时,程序会出现GUI冻结、无响应,最终进程终止的崩溃问题。最简复现代码如下:
private void toolTip1_Popup(object sender, PopupEventArgs e) { toolTip1.SetToolTip(e.AssociatedControl, "test"); }
测试中发现:
- 移除
SetToolTip调用后,Popup事件可正常触发,显示默认提示文本 - 先调用
MessageBox.Show再执行SetToolTip时,程序不会崩溃,但Tooltip不会正常显示,仅后续触发时生效 - 先执行
SetToolTip再调用MessageBox.Show时,程序直接崩溃
崩溃原因
调用ToolTip.SetToolTip方法会重新触发目标控件的Popup事件,形成无限递归循环:
- 鼠标 hover 触发控件的Popup事件
- 事件内调用
SetToolTip,强制重新触发该控件的Popup事件 - 递归调用不断消耗系统资源,最终导致程序崩溃
而先调用MessageBox.Show的情况能暂时避免崩溃,是因为MessageBox阻断了Tooltip的渲染流程,后续的递归触发被中断,但这并非正确的解决方案。
正确解决方案
不要在Popup事件中调用SetToolTip,而是直接修改PopupEventArgs.ToolTipText属性来动态设置提示文本。这个属性专门用于在Popup事件中调整显示内容,不会触发新的Popup事件,从根源避免递归:
private void toolTip1_Popup(object sender, PopupEventArgs e) { // 直接修改事件参数的文本,无递归风险 e.ToolTipText = "test"; }
如果需要针对不同控件设置不同的动态文本,可通过e.AssociatedControl判断目标控件后赋值:
private void toolTip1_Popup(object sender, PopupEventArgs e) { if (e.AssociatedControl == button1) { e.ToolTipText = "按钮1的动态提示"; } else if (e.AssociatedControl == textBox1) { e.ToolTipText = "输入框的动态提示"; } // 其他控件可保留默认提示,无需修改 }
内容的提问来源于stack exchange,提问作者APCrowder
相关产品推荐
相关产品推荐

