393 votes

CS0120 : Une référence d'objet est requise pour le champ, la méthode ou la propriété non statique 'foo'

Considérez:

espace de noms WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //int[] val = {0, 0};
            int val;
            if (textBox1.Text == "")
            {
                MessageBox.Show("Entrez un nombre");
            }
            else
            {
                val = Convert.ToInt32(textBox1.Text);
                Thread ot1 = new Thread(new ParameterizedThreadStart(SumData));
                ot1.Start(val);
            }
        }

        private static void ReadData(object state)
        {
            System.Windows.Forms.Application.Run();
        }

        void setTextboxText(int result)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result });
            }
            else
            {
                SetTextboxTextSafe(result);
            }
        }

        void SetTextboxTextSafe(int result)
        {
            label1.Text = result.ToString();
        }

        private static void SumData(object state)
        {
            int result;
            //int[] icount = (int[])state;
            int icount = (int)state;

            for (int i = icount; i > 0; i--)
            {
                result += i;
                System.Threading.Thread.Sleep(1000);
            }
            setTextboxText(result);
        }

        delegate void IntDelegate(int result);

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Pourquoi cette erreur se produit-elle?

Une référence d'objet est nécessaire pour le champ, la méthode ou la propriété non statique 'WindowsApplication1.Form1.setTextboxText(int)

540voto

Joe Points 5298

Il semble que vous appelez un membre non statique (une propriété ou une méthode, spécifiquement setTextboxText) à partir d'une méthode statique (spécifiquement SumData). Vous devrez soit:

  1. Si vous le pouvez, rendre setTextboxText statique:
    static void setTextboxText(int result)

CEPENDANT, dans ce cas, setTextboxText EXIGE l'accès aux variables d'instance, donc ne peut pas être statique.
Faites plutôt:

  1. Appelez setTextboxText via un singleton statique de Form1:

    class Form1 { public static Form1 It; // Singleton.

    public Form1()
    {
        It = this;
    }
    
    private static void SumData(object state)
    {
        ...
        It.setTextboxText(result);
    }

    }

  2. Créez une instance de Form1 dans la méthode d'appel:

    private static void SumData(object state)
    {
        int result = 0;
        //int[] icount = (int[])state;
        int icount = (int)state;
    
        for (int i = icount; i > 0; i--)
        {
            result += i;
            System.Threading.Thread.Sleep(1000);
        }
        Form1 frm1 = new Form1();
        frm1.setTextboxText(result);
    }

    MAIS cela ne fera pas ce que vous voulez, si une instance de Form1 existe déjà.
    Passer une instance de Form1 serait également une option.

  3. Rendre la méthode d'appel une méthode d'instance non statique (de Form1):

     private void SumData(object state)
     {
         int result = 0;
         //int[] icount = (int[])state;
         int icount = (int)state;
    
         for (int i = icount; i > 0; i--)
         {
             result += i;
             System.Threading.Thread.Sleep(1000);
         }
         setTextboxText(result);
     }

Plus d'informations sur cette erreur peuvent être trouvées sur MSDN.

25voto

COOLGAMETUBE Points 494

Pour ce cas, où vous souhaitez obtenir un Contrôle d'un Formulaire et recevez cette erreur, j'ai une petite de dérivation pour vous.

Allez dans votre Program.cs et changez

Application.Run(new Form1());

à

public static Form1 form1 = new Form1(); // Placez cette variable en dehors du constructeur
Application.Run(form1);

Maintenant, vous pouvez accéder à un contrôle avec

Program.form1.

Aussi : N'oubliez pas de définir votre niveau d'accès au contrôle sur Public.

Et oui, je sais, cette réponse ne correspond pas à l'appelant de la question, mais elle correspond aux internautes qui ont ce problème spécifique avec les contrôles.

21voto

Brian Rasmussen Points 68853

Vous démarrez un thread qui exécute la méthode statique SumData. Cependant, SumData appelle SetTextboxText qui n'est pas statique. Par conséquent, vous avez besoin d'une instance de votre formulaire pour appeler SetTextboxText.

26 votes

Cette réponse semble reformuler le problème. Cela n'explique pas pourquoi cela génère une erreur.

4 votes

@Robert Ni toutes les autres réponses non plus... ce commentaire était inutile

9voto

user3794031 Points 1

Votre méthode doit être statique

static void setTextboxText(int result)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new IntDelegate(SetTextboxTextSafe), new object[] { result }); 
    }
    else
    {
        SetTextboxTextSafe(result);
    }
}

2 votes

Cette méthode spécifique accède explicitement aux propriétés de l'instance (notamment this.InvokeRequired et this.Invoke) et ne peut donc pas être statique.

5voto

veggiebenz Points 176

Crédit à @COOLGAMETUBE pour m'avoir donné l'astuce qui a finalement fonctionné pour moi. Son idée était bonne mais j'ai rencontré un problème lorsque Application.SetCompatibleTextRenderingDefault était appelée après la création du formulaire. Donc, avec un petit changement, cela fonctionne pour moi :

static class Programme
{
    public static Form1 form1; // = new Form1(); // Placez cette variable en dehors du constructeur

    /// 
    /// Point d'entrée principal de l'application.
    /// 
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(form1 = new Form1());
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X