Question

Des erreurs se produisent sporadiquement lorsque nous essayons de mettre à jour une info-bulle, comme ceci

ToolTip.SetToolTip(myLabel, customDataStructure)

L'erreur que nous obtenons est une NullReferenceException: la référence d'objet n'est pas définie sur une instance d'objet

Quelqu'un connaît-il la cause de ceci?

Un simple Try / Catch qui mange la NullReferenceException est-il une option réalisable? Nous ne voulons pas que toute notre application explose quand nous l'obtenons.

Était-ce utile?

La solution

Je suppose que vous appelez ToolTip.SetTooltip à partir d'un gestionnaire d'événements et que ce gestionnaire se déclenche parfois avant la création de l'étiquette. Vous devriez probablement protéger cela en vérifiant que l'étiquette est null , puis assurez-vous que l'info-bulle est initialisée sur l'événement Load de l'étiquette.

Vous ne devriez certainement pas capturer l'exception car cela cache le problème.

Autres conseils

Ignorer les exceptions est rarement, voire jamais, une bonne idée. L'exception est levée car quelque chose ne va pas dans la mise en œuvre actuelle. En ignorant l'exception, l'application passe dans un état non défini et vous verrez probablement d'autres effets étranges dus à la référence manquante.

Comme cela est sporadique, il peut s'agir d'un problème de concurrence critique. Vous devez donc examiner attentivement le code pour déterminer s'il existe des situations dans lesquelles la référence peut être utilisée avant d'être correctement initialisée.

Essayez de vérifier si vous définissez cette variable dans n'importe quelle situation, en utilisant le débogueur par exemple ...

Une simple tentative / capture qui se nourrit de l'exception NullReferenceException est-elle une option réalisable?

Cela ne résoudrait pas le problème, il le cacherait. Une mauvaise pratique de programmation.

La cause la plus courante en est la fermeture d’une fenêtre et la validation qui définit une info-bulle sur un contrôle invisible.

Je n'ai pas débogué dans le code .Net, mais j'ai une assez bonne idée de l'endroit où l'erreur est renvoyée dans le code de l'info-bulle.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));
    }

La condition pour résoudre ce problème est très simple, vérifiez si le formulaire est visible ou que Benjamin RAIBAUD mentionne Disposing = false avant d'appeler la méthode SetToolTip des contrôles ToolTip:

C #:

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

VB.Net:

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

IMO C’est quelque chose qui devrait être géré par le .Net Framework ...

Je viens de rencontrer le même problème. Il semble que l'exception soit levée depuis la méthode ToolTip.CreateHandle () et qu'elle se produise uniquement sur la fenêtre enfant MDI. Avant d'appeler la méthode SetToolTip (...), assurez-vous que la propriété Disposing du formulaire parent est définie sur false. Quoi qu'il en soit, le formulaire est en cours d'élimination, de sorte que vous ne vous souciez plus des infobulles ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top