使用ToolTip.CreateHandle的NullReferenceException
-
05-07-2019 - |
题
当我们尝试更新工具提示时,我们偶尔会遇到错误,例如
ToolTip.SetToolTip(myLabel, customDataStructure)
我们得到的错误是 NullReferenceException:对象引用没有设置为对象的实例
有谁知道原因?
是一个简单的 Try / Catch
,它使 NullReferenceException
成为一个可行的选项吗?当我们得到这个时,我们不希望我们的整个应用程序爆炸。
解决方案
我猜你从一个事件处理程序调用 ToolTip.SetTooltip
,并且该处理程序有时会在创建标签之前触发。您应该通过检查标签为 null
来防范这一点,然后确保在标签的 Load
事件中初始化工具提示。
你当然不应该只是抓住异常,因为这会隐藏问题。
其他提示
忽略异常很少是一个好主意。抛出异常是因为当前实现中存在错误。通过忽略异常,应用程序基本上处于未定义状态,并且由于缺少引用,您很可能会看到其他奇怪的效果。
由于这是零星的,它可能是竞争条件问题,因此您必须仔细查看代码,以确定在正确初始化之前是否存在可以使用引用的任何情况。
尝试测试您是否在任何情况下使用调试器设置该var,例如......
是一个简单的Try / Catch,它使NullReferenceException成为一个可行的选项吗?
这不会解决问题,它会隐藏它。糟糕的编程习惯。
最常见的原因是当您关闭窗口并且发生验证时,会在不可见的控件上设置工具提示。
我没有调试到.Net代码,但是很清楚ToolTip.CreateHandle代码中引发错误的位置:
private void CreateHandle()
{
if (this.GetHandleCreated())
{
return;
}
IntPtr userCookie = UnsafeNativeMethods.ThemingScope.Activate();
try
{
SafeNativeMethods.InitCommonControlsEx(new NativeMethods.INITCOMMONCONTROLSEX
{
dwICC = 8
});
CreateParams createParams = this.CreateParams;
if (this.GetHandleCreated())
{
return;
}
//HERE! I suspect window is null when the form is closed
this.window.CreateHandle(createParams);
}
finally
{
UnsafeNativeMethods.ThemingScope.Deactivate(userCookie);
}
if (this.ownerDraw)
{
int num = (int)((long)UnsafeNativeMethods.GetWindowLong(new HandleRef(this, this.Handle), -16));
num &= -8388609;
UnsafeNativeMethods.SetWindowLong(new HandleRef(this, this.Handle), -16, new HandleRef(null, (IntPtr)num));
}
修复此问题的条件非常简单,只需检查表单是否可见,或者在调用ToolTip控件的SetToolTip方法之前,Benjamin RAIBAUD提到Disposing = false:
C#:
if (!this.Disposing) ttpHoverText.SetToolTip(targetControl, brokenText);
VB.Net:
If Me.Disposing = False Then ttpHoverText.SetToolTip(targetControl, brokenText)
IMO这应该由.Net Framework处理......
我遇到了同样的问题。似乎异常是从ToolTip.CreateHandle()方法中抛出的,它发生在仅部署的MDI子窗口上。在调用SetToolTip(...)方法之前,请确保父窗体的Disposing属性为false。无论如何,表格正在处理中,所以你不再关心工具提示......