简体   繁体   English

C#将文本添加到ListBox或TextBox

[英]C# add text to ListBox or TextBox

  1. Hello, I've got problem to write simple string to TextBox and ListBox. 您好,我在将简单字符串写入TextBox和ListBox时遇到问题。 I do not know what is wrong. 我不知道怎么了。 After click on button3 is in class Listen running method to open communication and receiving packets. 单击button3后,在类Listen运行方法中打开通信并接收数据包。 In this method (Listen.StartListen) is reference to PrintReceivedPackets. 在此方法中(Listen.StartListen)是对PrintReceivedPackets的引用。 Is it mistake in Task part? 任务部分有误吗? Is it better to use Thread instead of Task? 使用Thread代替Task更好吗?

2. 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. 最简单的方法是在Listen类中添加对主窗体的引用。 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: 然后,在button2_Click_1中,您可以创建如下的起始对象:

start = new Listen(this); 

And then, in PacketHandler, you can do: 然后,在PacketHandler中,您可以执行以下操作:

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. 并从PacketHandler中删除Form1 f = new Form1(),因为您实际上并不希望每个数据包都有一个新的表单。

In the PacketHandler you are creating a new Form1 instance and then calling PrintReceivedPackets method of that form. 在PacketHandler中,您将创建一个新的Form1实例,然后调用窗体的PrintReceivedPackets方法。 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. 根据代码判断,这种形式实际上是不会打开的,因为您需要在某个时候调用f.Show()或f.ShowSialog()。

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. 通过将主表单对象分配给全局变量,或将其作为参数传递给StartListen,使您的主表单对StartListen对象可见。

  2. In PacketHandler, call the PrintReceivedPackets method of the main form. 在PacketHandler中,调用主窗体的PrintReceivedPackets方法。 It's not quite apparent, in which thread the PacketHandler is executed. 在哪个线程中执行PacketHandler还不是很明显。 If you get a "cross-thread" exception, then you need to pass the update into main thread with Invoke, something like this: 如果遇到“跨线程”异常,则需要使用Invoke将更新传递到主线程中,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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