代码之家  ›  专栏  ›  技术社区  ›  Joe Morgan

具有tooltip.createHandle的NullReferenceException

  •  0
  • Joe Morgan  · 技术社区  · 17 年前

    当我们试图更新一个工具提示时,偶尔会出错,如下所示

    ToolTip.SetToolTip(myLabel, customDataStructure)
    

    我们得到的错误是 NullReferenceException: Object reference not set to an instance of an object

    有人知道原因吗?

    是简单的 Try/Catch 吃了 NullReferenceException 可行的选择?我们不希望我们的整个应用程序在收到这个消息时崩溃。

    5 回复  |  直到 10 年前
        1
  •  1
  •   Jeff Yates    17 年前

    我猜你在打电话 ToolTip.SetTooltip 来自事件处理程序,该处理程序有时会在创建标签之前激发。你应该检查一下标签 null 然后确保工具提示在标签上初始化 Load 事件。

    你当然不应该只是抓住例外,因为这掩盖了问题。

        2
  •  1
  •   Brian Rasmussen    17 年前

    忽略例外很少是一个好主意。由于当前实现中存在错误,引发了异常。通过忽略异常,应用程序基本上会以未定义的状态进行,您很可能会看到由于缺少引用而产生的其他奇怪的效果。

    由于这是偶发性的,可能是一个争用条件问题,因此您必须仔细查看代码,以确定在正确初始化引用之前是否存在可以使用该引用的情况。

        3
  •  1
  •   cort    17 年前

    尝试测试在任何情况下是否设置该var,例如使用调试器…

    一个简单的Try/Catch接受NullReferenceException是一个可行的选项吗?

    这不能解决问题,它会隐藏问题。糟糕的编程实践。

        4
  •  1
  •   Jeremy Thompson    10 年前

    最常见的原因是当关闭一个窗口并进行验证时,会在不可见控件上设置工具提示。

    我没有调试到.NET代码中,但对工具提示中引发错误的位置有了很好的了解。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));
        }
    

    修复此问题的条件非常简单,只需在调用工具提示控件settooltip方法之前检查表单是否可见或本杰明·拉博德提到disposing=false:

    C:

    if (!this.Disposing) ttpHoverText.SetToolTip(targetControl, brokenText);
    

    VB.NET:

    If Me.Disposing = False Then ttpHoverText.SetToolTip(targetControl, brokenText)
    

    IMO这是应该由.NET框架处理的内容…

        5
  •  0
  •   Benjamin RAIBAUD    16 年前

    我也遇到了同样的问题。似乎异常是从tooltip.createHandle()方法中抛出的,并且它只在正在释放的MDI子窗口上发生。在调用settooltip(…)方法之前,请确保父窗体的disposing属性为false。不管怎样,表单正在被释放,所以您不再真正关心工具提示了…