如何将项目从另一个类和另一个线程添加到列表框?

时间:2018-03-23 13:07:08

标签: c# class listbox delegates

我试过了:

partial class MainForm : Form
{
    Logging logging= new Logging();

    public MainForm()
    {
        InitializeComponent();
    } 

    private void add()
    {
        while (true)
        {
            logging.add_data_to_listbox("sometext",listBox1);
        }
    }

    private void help_button_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(add);
    }

}

public partial class Logging
{

    public void add_data_to_listbox(string data, ListBox listbox)
    {
        MainForm mnfrm = new MainForm();

        mnfrm.Invoke(new MethodInvoker(delegate ()
        {
            listbox.Items.Add(DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss.fff - ") + data);
        }));
    }
}

但我收到此错误消息: 附加信息:在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。

1 个答案:

答案 0 :(得分:0)

MainForm已将LoggingClass作为属性。现在您在Logging中再次创建MainForm?

我认为你应该在Logging类中创建一个EventHandler LogMessage并从MainForm订阅它。之后在方法中你可以处理有效的事情,如:

Logging:
// event handler
public event EventHandler<EventArgs> LogMessageReceived; 

// send log message
public void add_data_to_listbox(string data, ListBox listbox)
{
    LogMessageReceived?.Invoke(new EventArgs());
}

MainForm:
public MainForm()
{
    InitializeComponent();
    logging.LogMessageReceived += OnLogMessageReceived;
} 

private void OnLogMessageReceived(object sender, EventArgs eventArgs)
{
    // switch thread to STA thread?
    Invoke(new MethodInvoker(delegate ()
        {
            listbox.Items.Add(DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss.fff - ") + data);
        }));
}

您仍然需要创建自己的自定义事件参数。