2010-12-03 4 views
1

J'ai créé un contrôle personnalisé avec une valeur maximale. Lors de l'ajout de if (DesignMode) Parent.Refresh(); il compile, mais dans le client, il se bloque avec l'erreur de message:Winform Custom Control Pourquoi "Référence d'objet n'est pas définie sur une instance d'un objet"?

Object Reference not set to an instance of an object 

pile d'appel:

at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value) 
at Microsoft.VisualStudio.Shell.Design.VsTargetFrameworkPropertyDescriptor.SetValue(Object component, Object value) 
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializePropertyAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement, CodePropertyReferenceExpression propertyReferenceEx, Boolean reportError) 
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement) 
at System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement) 

code source:

[Category("Main")] 
    [Description("Max Value")] 
    [DefaultValue(100)] 
    public int Max 
    { 
     get { return _max; } 
     set { 
      _max = value; 
      if (DesignMode) 
      { 
       Parent.Refresh(); 
      } 
     } 
    } 
+0

Pourquoi actualisez-vous le parent? Je n'ai jamais vu ce comportement désiré ou nécessaire. –

Répondre

4

essayez ceci:

if (DesignMode && Parent != null) 
    { 
     Parent.Refresh(); 
    } 

La plupart probablement le contrôle n'a pas encore été ajouté à son parent lorsque la valeur est définie pour la première fois.

Si vous examinez le fichier * .designer.cs de votre formulaire, vous remarquerez que les propriétés de votre commande usercontent avant que soit ajoutée au formulaire parent. C'est pourquoi vous obtenez l'exception.

+1

+1 Pour Botz3000 - Je sais que cela a déjà été mentionné mais je voulais juste dire explicitement: si vous avez des propriétés publiques dans le code de votre contrôle, alors le fichier du concepteur parent (où réside votre contrôle personnalisé) prendra la liberté de initialiser votre propriété à null (ou Nothing pour VB.Net). Le pire, c'est que parfois cela ne se produira que beaucoup plus tard, ce qui explique pourquoi il semble que cette erreur ne se produise parfois nulle part. Si vous ajoutez votre contrôle au parent, puis ajoutez la propriété publique au code du contrôle, le concepteur peut le récupérer plus tard plutôt que plus tôt. – dyslexicanaboko

0

Vous devez également vérifier null pour Parent et également assurez-vous que vous définissez l'objet parent ou le Parent.Refresh() n'exécutera jamais.

2

J'ai eu un problème similaire. Le code du composant a provoqué cette erreur. La solution simple dans mon cas a été Englober tous les code qui fonctionne avec des composants graphiques:

if (this.Created) 
{ 
    // insert code with other components here 
} 

Malheureusement, cette solution ne fonctionne pas correctement avec le contrôle onglet (lorsque le composant est pas premier onglet visible).

Dans mon cas, le problème était dû à une propriété. La propriété a une initialisation active des composants enfants. La solution finale est:

[EditorBrowsable(EditorBrowsableState.Never)] 
[Browsable(false)] 
[Category("Main")] 
[Description("...")] 
[DefaultValue(MyDataClass.None)] 
public MyDataClass Data 
{ 
    get 
    { 
    return this.data; 
    } 
    set 
    { 
    if (object.ReferenceEquals(value, null)) 
     value = MyDataClass.None; // not null - valid state of no data 
    if (this.Created) 
    { 
     this.textEdit.Text = value.ToString(); 
    } 
    this.data = value; 
    } 
} 

protected override void OnVisibleChanged(EventArgs e) 
{ 
    base.OnVisibleChanged(e); 
    if (!this.DesignMode) 
    this.Data = this.data; 
} 

Pour éliminer l'utilisation d'erreur soit [Browsable(false)] ou remplacer OnVisibleChanged.

+0

en incluant le code à l'intérieur de 'if (this.Created) {}' dans le setter a corrigé le problème dans mon cas. Merci! grande aide!! –

Questions connexes