Search code examples
c#c#-4.0telnet

How to fix when trying to add data values to a listbox from another form


I am having an issue while trying to add data to a listbox from my main form, I am trying to add data to that list from a new class in my project, I need that new class to be able to add data to my listbox without errors, I am trying to use a invoke and I am getting the following error (System.InvalidOperationException: 'Invoke or BeginInvoke cannot be called on a control until the window handle has been created.') I have seen that error in other questions in stack overflow but similar to my issue, I will be adding both classes of my code here, one is the main class and the other a second class I created that will need to add data to the listbox. the data is coming from a telnet tcp/ip and port 23 that connection is working fine, the problem is adding that data to my listbox.

Main class calling the functions from my other class

namespace BarcodeReceivingApp {

//TelnetConnection stopConnection = new TelnetConnection();
public partial class BarcodeReceivingForm : Form
{
    //GLOBAL VARIABLES
    const string Hostname = "myip";
    private const int Port = 23;


    public BarcodeReceivingForm()
    {
        InitializeComponent();
    }

    private void btn_ConnectT_Click(object sender, EventArgs e)
    {

        var readData = new TelnetConnection(Hostname, Port);
        readData.ServerSocket(Hostname, Port);

    }

    private void btn_StopConnection_Click(object sender, EventArgs e)
    {
        //var connection = new TelnetConnection(Hostname, Port);
       // connection.CloseConnection();
    }
}

}

class that will change the data of my listbox from the main class.

 namespace BarcodeReceivingApp

{ public class TelnetConnection { public BarcodeReceivingForm BcForm = new BarcodeReceivingForm();

    private Thread _readWriteThread;
    private TcpClient _client;
    private NetworkStream _networkStream;
    private string _hostname;
    private int _port;

    public TelnetConnection(string hostname, int port)
    {
        this._hostname = hostname;
        this._port = port;
    }

    public void ServerSocket(string ip, int port)
    {

        try
        {
            _client = new TcpClient(ip, port);         
        }
        catch (SocketException)
        {
            MessageBox.Show(@"Failed to connect to server");
            return;
        }

        //Assign networkstream
        _networkStream = _client.GetStream();

        //start socket read/write thread
        _readWriteThread = new Thread(ReadWrite);
        _readWriteThread.Start();
    }

    public void ReadWrite()
    {

        //Set up connection loop
        while (true)
        {
            var command = "test";
            if (command == "STOP1")
                break;

            //write(command);
             var received = Read();


            BcForm.lst_BarcodeScan.Invoke(new Action (() => BcForm.lst_BarcodeScan.Items.Add(received)));


        }

    }

    public string Read()
    {
        byte[] data = new byte[1024];
        var received = "";

        var size = _networkStream.Read(data, 0, data.Length);
        received = Encoding.ASCII.GetString(data, 0, size);

        return received;
    }

    public void CloseConnection()
    {
        _networkStream.Close();
        _client.Close();
    }
}
}

the final results like I said is my ReadWrite method when running the loop will add the data to my listbox from my main form class

here the image where I get the error Image of Error


Solution

  • Write your second class like this

    using System;
    using System.Threading;
    using System.Windows.Forms; 
    namespace BarcodeReceivingApp { 
        public class TelnetConnection { 
    
            private Thread _readWriteThread;
            private TcpClient _client;
            private NetworkStream _networkStream;
            private string _hostname;
            private int _port;
            private Form foo;
    
            public TelnetConnection(string hostname, int port)
            {
                this._hostname = hostname;
                this._port = port;
            }
    
            public void ServerSocket(string ip, int port,Form f)
            {
                this.foo = f;
                try
                {
                    _client = new TcpClient(ip, port);         
                }
                catch (SocketException)
                {
                    MessageBox.Show(@"Failed to connect to server");
                    return;
                }
    
                _networkStream = _client.GetStream();
    
                _readWriteThread = new Thread(ReadWrite());
                _readWriteThread.Start();
            }  
    
            public void ReadWrite()
            {
                while (true)
                {
                    var command = "test";
                    if (command == "STOP1")
                        break;
    
                    //write(command);
                     var received = Read();
                     if (foo.lst_BarcodeScan.InvokeRequired)
                     {
                             foo.lst_BarcodeScan.Invoke(new MethodInvoker(delegate {foo.lst_BarcodeScan.Items.Add(received);}));
                     }
                }
            }
    
            public string Read()
            {
                byte[] data = new byte[1024];
                var received = "";
    
                var size = _networkStream.Read(data, 0, data.Length);
                received = Encoding.ASCII.GetString(data, 0, size);
    
                return received;
            }
    
            public void CloseConnection()
            {
                _networkStream.Close();
                _client.Close();
            }
        }
    }
    

    Then use it like this from your main class:

    private void btn_ConnectT_Click(object sender, EventArgs e)
    {
    
        var readData = new TelnetConnection(Hostname, Port);
        readData.ServerSocket(Hostname, Port, this);
    
    }