Question

We sporadically get errors when we try to update a tool tip, like this

ToolTip.SetToolTip(myLabel, customDataStructure)

The error we get is a NullReferenceException: Object reference not set to an instance of an object

Does anyone know the cause of this?

Is a simple Try/Catch that eats the NullReferenceException a feasible option? We don't want our entire application to blow up when we get this.

Was it helpful?

Solution

I would guess that you're calling ToolTip.SetTooltip from an event handler and that handler sometimes fires before the label has been created. You should probably guard this with a check for the label being null and then make sure that the tool tip is initialised on the label's Load event.

You certainly shouldn't just catch the exception as this hides the problem.

OTHER TIPS

Ignoring exceptions is rarely if ever a good idea. The exception is thrown because something is wrong in the current implementation. By ignoring the exception the application basically proceeds in an undefined state and you will most likely see other weird effects due to the missing reference.

Since this is sporadic it could be a race condition issue, so you have to look carefully at the code to figure out if there are any situations in which the reference may be used before it is correctly initialized.

Try to test whether you're setting that var in any situation, using the debugger for example...

Is a simple Try/Catch that eats the NullReferenceException a feasible option?

That wouldn't solve the problem, it would hide it. A bad programming practice.

The most common cause of this is when you close a Window and Validation occurs that sets a ToolTip on an invisible control.

I haven't debugged into the .Net Code but have a pretty good idea where the error is thrown in the ToolTip.CreateHandle's code:

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

The condition to fix this is very simple, just check if the form is visible or as Benjamin RAIBAUD mentions Disposing = false before calling the ToolTip controls SetToolTip method:

C#:

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

VB.Net:

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

IMO This is something that should be handled by the .Net Framework...

I just ran into the same problem. It seems the exception is thrown from within the ToolTip.CreateHandle() method and it happens on MDI child window being disposed only. Before calling the SetToolTip(...) method, make sure the Disposing property of the parent form is false. Anyway, the form is being disposed, so you don't really care about the tooltips anymore...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top