简体   繁体   中英

C# add text to ListBox or TextBox

  1. Hello, I've got problem to write simple string to TextBox and ListBox. I do not know what is wrong. After click on button3 is in class Listen running method to open communication and receiving packets. In this method (Listen.StartListen) is reference to PrintReceivedPackets. Is it mistake in Task part? Is it better to use Thread instead of Task?

2.

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private Listen lis, start;
        public Form1()
        {
            InitializeComponent();
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            string deviceNum = comboBox2.Text;
            char dN = deviceNum[0];
            start = new Listen();
            Task.Factory.StartNew(() => start.StartListen(dN));

        }

        private void button3_Click(object sender, EventArgs e)
        {
            lis = new Listen();
            var devices = lis.GetDevices();
            comboBox2.DataSource = devices;
        }

        public void PrintReceivedPackets(string packetInfo)
        {
            //  Do not work 
            Console.WriteLine(">>>" + packetInfo);
            listBox1.Items.Add(packetInfo);
            textBox1.AppendText(packetInfo);
        }

    }

Methods in Class Listen

public void StartListen(char deviceNum)
        { 
            int deviceNumber = (int)Char.GetNumericValue(deviceNum);

            // Take the selected adapter
            PacketDevice selectedDevice = allDevices[deviceNumber - 1];

            // Open the device
            using (PacketCommunicator communicator =
                selectedDevice.Open(65536,                                  // portion of the packet to capture
                                                                            // 65536 guarantees that the whole packet will be captured on all the link layers
                                    PacketDeviceOpenAttributes.Promiscuous, // promiscuous mode
                                    1000))                                  // read timeout
            {
                Console.WriteLine("Listening on " + selectedDevice.Description + "...");

                // start the capture
                communicator.ReceivePackets(0, PacketHandler);
            }
        }

        // Callback function invoked by Pcap.Net for every incoming packet
        public void PacketHandler(Packet packet)
        {
            Console.WriteLine(packet.Timestamp.ToString("dd-MM-yyyy ") + " length:" + packet.Length + " " + packet.DataLink);
            string packetInfo = packet.Timestamp.ToString("dd-MM-yyyy ") + " length:" + packet.Length + " " + packet.DataLink;

            Form1 f = new Form1();
            f.PrintReceivedPackets(packetInfo);
        }

Edit: added comments on how to make the main form visible to the Listener

The easiest way would be to add a reference to the main form to your Listen class. A'la:

public class Listen
{
    Form1 mainForm;

    public Listen(Form1 mainForm)
    {
        this.mainForm = mainForm;

        ...
    }
}

Then, in button2_Click_1 you can create the start object like this:

start = new Listen(this); 

And then, in PacketHandler, you can do:

mainForm.Invoke((Action)(() => mainForm.PrintReceivedPackets(packetInfo)));

And remove Form1 f = new Form1() from the PacketHandler, as you dont actually want a new form for every packet.

In the PacketHandler you are creating a new Form1 instance and then calling PrintReceivedPackets method of that form. That form, judging by the code, is never actually opened - for that you would need to call f.Show() or f.ShowSialog() at some point.

If your intent is to display the packet notification of the actual main form, then you need to do two things:

  1. Make your main form visible to the StartListen object, by either assigning the main form object to a global variable, or pass it into StartListen as parameter.

  2. In PacketHandler, call the PrintReceivedPackets method of the main form. It's not quite apparent, in which thread the PacketHandler is executed. If you get a "cross-thread" exception, then you need to pass the update into main thread with Invoke, something like this:

    mainForm.Invoke((Action)(() => mainForm.PrintReceivedPackets(packetInfo)));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM