从另一个类中的另一个线程创建和显示 WindowsForm - C#

问题描述

第一:我知道这个问题已经被问过很多次了,但我确实在这个问题上停滞了几个小时,而且我没有成功地应用我发现的不同解决方案我的问题。

我有一个这样的课程:

class Program
{
    private static UDProtocol MyUdp;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        MyUdp = new UDProtocol();
        MyUdp.Start();
        Application.Run();
    }
}

还有一个 UDProtocol 类,我把它简化成这样:

class UDProtocol
{
    UdpMe = new UdpClient(11000);

    public void Start()
    {
        new Thread(() =>
        {
            CreateNewForm();

        }).Start();
     }

    public void CreateNewForm()
    {
        //Form f1 = new Form()
        //f1.Show()
    }
  }

当我这样做时(使用 CreateNewForm 中的注释),我显示了我的表单,但其上的控件都是透明的,如下所示:

enter image description here

我认为这是因为试图在不同的线程中创建一个 from,我很确定我应该使用 Invoke,但我真的不知道该怎么做。

谢谢

编辑:解决方

Application.Run(new Form());

在线程中添加它可以解决问题。表单正确显示

解决方法

UDProtocol 对象应生成自定义 Form 可用于向用户显示信息的事件。

class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        MyForm f1 = new MyForm();
        Application.Run(f1);
    }
}

public class UDProtocol {

    public event EventHandler SomeEvent;

    Thread tRead = null;
    public void Start() {
        // some internal thread starts
        if (tRead != null)
            throw new Exception("Already started.");

        tRead = new Thread(() => {
            while (true) {
                Thread.Sleep(1000);
                if (SomeEvent != null)
                    SomeEvent(this,EventArgs.Empty);
            }
        });
        tRead.IsBackground = true;
        tRead.Name = "UDProtocol.Read";
        tRead.Start();
    }
}

public class MyForm : Form {
    UDProtocol myUDP = new UDProtocol();

    public MyForm() {
        myUDP.SomeEvent += udp_SomeEvent;
    }

    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        myUDP.Start();
    }

    void udp_SomeEvent(object sender,EventArgs e) {
        this.BeginInvoke((Action) delegate {
            MessageBox.Show(this,"Some event happened in the UDP object.","UDP Event");
        });
    }
}