首页 > 解决方案 > 从另一个类中的另一个线程创建和显示 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 中的注释),我显示了我的表单,但它上面的控件都是透明的,如下所示:

在此处输入图像描述

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

谢谢

编辑:解决方案

Application.Run(new Form());

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

标签: c#multithreadingwinformsclassinvoke

解决方案


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");
        });
    }
}

推荐阅读