Laden...

Zugriff auf Form-Elemente

Erstellt von Lemiel07 vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.989 Views
L
Lemiel07 Themenstarter:in
11 Beiträge seit 2007
vor 16 Jahren
Zugriff auf Form-Elemente

hallo zusammen,
ich bin kein C# Profi.(habe früher was mit c++ was gemacht ..)
ich habe ein Programm geschrieben, welches aus 2 Dateien besteht aber mit dem gleichen namespace.

Datei1.cs : //In der steht der code für das GUI und wird mein TCP-Server instanziert


namespace myTest
{
    public class MainForm : System.Windows.Forms.Form
    {
          //....

          //...
          ThreadTcpServer  server;
         
          private void button4_Click(object sender, EventArgs e)
          {
              server = new ThreadTcpServer();
              button4.Enabled = false;
          }
          
         public void formFunktion()
         {
                 //....

                  //...
         }
   
     }
    
}

Datei2.cs // TCP server Klassen bzw. mein Background-Threads


namespace myTest
{
    public class public class ThreadTcpServer 
    {
          //....

          //...
           public ThreadTcpServer 
           {
                servMainThread = new Thread(new ThreadStart(this.mainListener));
                servMainThread.IsBackground = true;
                servMainThread.Start();

            }
          private void mainListener()
          {
                VerbindungThread newconnection = new VerbindungThread();
                newconnection.threadListener = this.client; 
                Thread newthrd = new Thread(new ThreadStart(newconnection.verbindungHandler));
                newthrd.IsBackground = true;
                newthrd.Start();           
           }
    }
    
    class VerbindungThread
    {
          //....
           
          //...  
           myTest.MainForm mf = new MainForm();

            public void verbindungHandler()
            {
                   //....
                        // Hier wird code einwandfrei ausgeführt
                  //...
                 
                   mf.textBox2.Text = "received";  // wird nie  angezeigt!!!!!!!!!!????????
                   mf.formFunktion();  // dieser Aufruf scheitert und bricht mein Prog. ab !!!!!!!!!!???????????
                                      
                  
            }
    }
}

wenn ich meine Applikation starte und mit Hilfe einer Client-Anwendung mein Server anspreche wird die Verbindung einwandfrei aufgebaut aber nur Zugriff auf die Form-Steuerelemente bzw. deren Funktion misslingt wie oben im Code kommentiert.
was mache ich hier falsch oder was soll noch implementieren damit das ganze zusammenarbeitet? hoffe das ich mich verständlich ausgedruckt habe.
Vielen Dank. ich bin auf ihre Hilfe angewiesen

Gelöschter Account
vor 16 Jahren

hallo

wenn


public void verbindungHandler()

der konstruktor sein soll musst du es so schreiben


public VerbindungHandler()

ansonsten seh ich da auch keinen fehler

MfG janismac

A
254 Beiträge seit 2007
vor 16 Jahren

hallo,

ich denke es liegt daran, dass Du aus einem anderen Thread aus auf die Oberfläche zugreifst.

Deklariere einen delegate für Deine Oberflächenfunktion und rufe diese Funktion mit Invoke auf. Den Text kannst Du ja als Parameter übergeben.

Bin mir nicht sicher, kannst es ja mal ausprobieren.

Tschüss

49.485 Beiträge seit 2005
vor 16 Jahren
L
Lemiel07 Themenstarter:in
11 Beiträge seit 2007
vor 16 Jahren

Vielen Dank für eure Antworten
@ janismac -> Das ist kein konstruktor.
@ a957m -> Deine Idee ist interessant. wird ich später probieren
@ herbivore -> mit Hilfe deines Links, habe ich folgendes implementiert:

In der **Datei1.cs **

 
public void reactionOnServer()
{        
      textBox2.Text = "Text kommt vom Server";
        
      this.formFunktion();       
}

in der **Datei2.cs **rufe ich die GUI-Elemente per "invoke" auf


class VerbindungThread
{
          //....
           
          //...  
           myTest.MainForm mf = new MainForm();

            public void verbindungHandler()
            {
                   //....
                        // Hier wird code einwandfrei ausgeführt
                  //...
                 
                 //  mf.textBox2.Text = "received";  // wird nie  angezeigt!!!!!!?????
                //   mf.formFunktion();  // dieser Aufruf scheitert  !!!!!!!!!!???????????
                
             mf.textBox2.Invoke(new MethodInvoker(mf.reactionOnServer());
        
            }
}


dann bekam ich die Fehlemeldung:

"Invoke oder BeginInvoke kann für ein Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde."

Aufgrunddessen habe ich, wie im Link, folgendes in der ** Datei1.cs **implementiert


//Im konstruktor
public MainForm()
{
      InitializeComponent();
      this.CreateHandle();  // habe hier 
}

und jetzt bekomme ich den folgenden Fehler:

Der Objektverweis wurde nicht auf eine Objektinstanz 
festgelegt.

was soll ich noch tun?. bitte hilft mir?
Danke sehr

L
Lemiel07 Themenstarter:in
11 Beiträge seit 2007
vor 16 Jahren

Hallo

ich habe es gemacht


class VerbindungThread
{
          //....
           
          //...  
           myTest.MainForm mf = new MainForm();

            public void verbindungHandler()
            {
                   //....
                        // Hier wird code einwandfrei ausgeführt
                  //...
                 
                 //  mf.textBox2.Text = "received";  // wird nie  angezeigt!!!!!!?????
                //   mf.formFunktion();  // dieser Aufruf scheitert  !!!!!!!!!!???????????
                 if (mf != null)
                 {
                    mf.textBox2.Invoke(new MethodInvoker(mf.reactionOnServer());          
                 }
            }
} 

aber trotzdem kommt nach wie vor die Fehlermeldung:

Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

ich bin ahnunglos. bitte sagt mir was ich da falsch mache?
Vielen vielen Dank

822 Beiträge seit 2005
vor 16 Jahren

Wir können dir nicht helfen, wir haben nicht deinen gesamten Code...

Setzt doch mal Haltepunkte im Debugger und schau dir die Werte deiner Variablen an, da ist sicher eine davon null...

sbertl

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Lemiel07,

lies bitte nochmal [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt . Dann weißt du auch, warum du viel selbst machen muss, aber auch kannst.

herbivore

L
Lemiel07 Themenstarter:in
11 Beiträge seit 2007
vor 16 Jahren

Guten morgen,
@herbivore
ich habe den link mehrere mals gelesen. Alles was ich machen konnte ist oben im code implemntiert. vielleicht übersehe ich was !!! ich bin an meiner Grenzen gestoßen.
sieht ihr was oder was mache ich fasch!???
Danke

822 Beiträge seit 2005
vor 16 Jahren

Versteh uns doch, wie sollen wir dir helfen, du sagst uns deine Fehlermeldung: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
1.Woher sollen wir wissen, an welcher Stelle dein Fehler auftritt 1.Wir können auch nicht wissen, welche Werte deine Variablen haben, oder welche null sind

Also wirf mal den Debugger an, setz Haltepunke und schau dir die Variablen an, ob vlt. doch eine davon null ist.

sbertl

L
Lemiel07 Themenstarter:in
11 Beiträge seit 2007
vor 16 Jahren

Guten morgen,
Also hier ist mein gesamte Code. ich habe versucht 3 oder 4 Varianten (siehe Code) aus dem Server-Thread auf das GUI zugreifen aber leider sind alle Versuche gescheitert. Vielleicht ist mein Server nicht gut gestaltet oder gibt´s andere Möglichketen ..

Form1.cs : //In der steht der code für das GUI und wird mein TCP-
Server instanziert


namespace MyTest 
{ 
    public partial class Form1 : Form 
    { 
        myServer server; 
        public delegate void ComEventCb(); 
        public delegate void controlsUpdateDelegate (string received); 


        public Form1() 
        { 
            InitializeComponent(); 
            this.CreateHandle(); 
        } 


        private void button1_Click(object sender, EventArgs e) 
        { 
            server = new myServer(); 
            button1.Enabled = false; 
            toolStripStatusLabel1.Text = " Server Modus"; 
        } 


        public void guiCB() 
        { 
            textBox1.Text = "sReceived"; 
            MessageBox.Show(" greife auf die Form zu", "MessageBox", 
                                MessageBoxButtons.OK, MessageBoxIcon.Information); 
            toolStripStatusLabel2.Text = "sReceived"; 
        } 


        public void controlsUpdate(string received) 
        { 
           if (this.InvokeRequired) 
            { 
                this.BeginInvoke(new controlsUpdateDelegate(controlsUpdate), 
                                          new object[] { received }); 


                return; 
            } 


            textBox2.Text = received; 


        } 
    } 


} 


MyServer.cs // TCP server Klassen bzw. mein Background-Threads


using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 


using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Windows.Forms; 


namespace MyTest 
{ 
    public class myServer 
    { 
        private TcpListener client; 


        /// <summary> /// Der Haupt-Thread /// </summary> 
        public Thread servMainThread; 


        int clientCounter = 0;  // maximale Anzahl an eingehenden Verbindungen 

        // Der Standard Konstruktor 
        public myServer() 
        { 
            // Hauptthread wird instanziiert ... 
            servMainThread = new Thread(new ThreadStart(this.mainListener)); 
            // als Background-thread, damit wird er gestoppt bei einem Applikation Ende 
            servMainThread.IsBackground = true; 
            // ... und gestartet 
            servMainThread.Start(); 


        } 



        private void mainListener() 
        { 
            client = new TcpListener(IPAddress.Parse("127.0.0.1"), 8000); 
            client.Start(); 

            //while (true) 
            while (clientCounter < 3) 
            { 
                //prüfe ob Verbindungsanforderungen anstehen 
                while (!client.Pending()) 
                { 
                    Thread.Sleep(500); 
                } 


                ConnectionThread newconnection = new ConnectionThread(); 
                newconnection.threadListener = this.client; 


                Thread newthread = new Thread(new ThreadStart(newconnection.VerbindungHandler)); 
                newthread.IsBackground = true; 
                newthread.Start(); 

                clientCounter++; 
            } 


        } 


    } 


    class ConnectionThread 
    { 
        public TcpListener threadListener; 
        private static int connections = 0; 


        MyTest.Form1 mf = new Form1(); 

        public void VerbindungHandler() 
        { 
            int recv; 
            byte[] data = new byte[1024]; 


            TcpClient client = threadListener.AcceptTcpClient(); 


            // Den Netzwerk-Stream abrufen. 
            NetworkStream ns = client.GetStream(); 
            connections++; 


            string welcome = "Willkomen bei MyServer"; 
            data = Encoding.ASCII.GetBytes(welcome); 
            ns.Write(data, 0, data.Length); 


            while (true) 
            { 
                //ns.DataAvailable: ruft einen Wert ab,der angibt, ob im Networkstream Daten 
                // für einen Lesevorgang verfügbar sind 
                if (ns.DataAvailable) 
                { 
                    data = new byte[1024]; 
                    recv = ns.Read(data, 0, data.Length); 


                    string sReceived = Encoding.Default.GetString(data, 0, recv); 

                    if (sReceived == "hallo") 
                    { 
                        if (mf != null) 
                        { 
                           // 1. Variante !!!!!!!!!???????
                           // mf.BeginInvoke(new MyTest.Form1.ComEventCb(mf.guiCB)); 

                            if (mf.InvokeRequired) 
                             { 
                               //2. Varainte !!!!!!!!!???????
                                //  mf.Invoke(new MyTest.Form1.ComEventCb(mf.guiCB)); 
                              
                               // 3.Variante !!!!!!!!!?????
                                //  mf.BeginInvoke(new MyTest.Form1.ComEventCb(mf.guiCB)); 

                             } 


                            //4. Variante !!!!!!!!!!!!!!?????????
                             mf.controlsUpdate(sReceived); 
                             Thread.Sleep(1000); 


                        } 


                    } 


                    ns.Write(data, 0, recv); 


                } 
            } 
            ns.Close(); 
            client.Close(); 
            connections--; 


        } 


    } 



} 


wenn ich meine Applikation starte und mit Hilfe einer Client-Anwendung mein Server anspreche wird die Verbindung einwandfrei aufgebaut aber nur Zugriff auf die Form-Steuerelemente bzw. deren Funktion misslingt wie oben im Code kommentiert.
was mache ich hier falsch oder was soll noch implementieren damit das ganze zusammenarbeitet? hoffe das ich mich verständlich ausgedruckt habe.
Vielen Dank. ich bin auf ihre Hilfe angewiesen