Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从C中的类更新GUI的正确方法#_C#_Multithreading_Class_User Interface - Fatal编程技术网

C# 从C中的类更新GUI的正确方法#

C# 从C中的类更新GUI的正确方法#,c#,multithreading,class,user-interface,C#,Multithreading,Class,User Interface,我正在寻找一种方法,从一个我希望独立且不依赖GUI的类更新GUI。它是一个由侦听器和客户端组成的网络类。此类可以连接然后发送/接收数据。我希望这些数据能够使用GUI显示,但在类本身中没有任何与GUI相关的代码 简言之,网络类只知道自己。GUI知道网络类 这就是我想添加代码的地方 public void ReceiveBytes() { byte[] receivedPacket; while (IsListeningForBytes)

我正在寻找一种方法,从一个我希望独立且不依赖GUI的类更新GUI。它是一个由侦听器和客户端组成的网络类。此类可以连接然后发送/接收数据。我希望这些数据能够使用GUI显示,但在类本身中没有任何与GUI相关的代码

简言之,网络类只知道自己。GUI知道网络类

这就是我想添加代码的地方

    public void ReceiveBytes()
    {
        byte[] receivedPacket;

        while (IsListeningForBytes)
        {
            receivedPacket = new byte[Packet.BUFFERSIZE];

            try
            {
                int bytesRead = ClientSocket.Receive(receivedPacket, SocketFlags.None);

                if (bytesRead > 0)
                {
                    SocketObject.ProcessMessage(receivedPacket);
                    // Update GUI here after the message has been processed.
                }
                else
                {
                    throw new Exception("No bytes read");
                }
            }
            catch (Exception ex)
            {
                IsListeningForBytes = false;
                Disconnect();
                Console.WriteLine(ex.Message);
            }
        }
    }
编辑:对不起,各位,我会尽量把事情弄清楚。我使用的是windows窗体,为了进行此练习,我们将说我有三个不同的控件:一个列表框、一个组合框和一个文本框,它们将根据发送的内容获取数据。(我的实际应用程序有需要更新的列表框、组合框、复选框等)

我知道我不应该从我的对象中引用GUI,因此我的问题是

至于相关代码,我不知道你想看什么

我已经阅读了EventHandler和委托,但我不确定在这种情况下如何实际实现它。我最初将一个GUI更新方法作为一个操作传递给在需要时调用的类,但这似乎很冗长,没有专门更新我想要的控件


感谢您迄今为止的帮助。

直接从对象更新UI将违反OOP

相反,实现一个事件,让调用方/用户知道发生了什么,并让他们负责更新UI

下面是一个例子:

//added event, SomeDataObject is for you to create.
public event EventHandler<SomeDataObject> MessageProcessed;
public void ReceiveBytes()
{
    byte[] receivedPacket;

    while (IsListeningForBytes)
    {
        receivedPacket = new byte[Packet.BUFFERSIZE];

        try
        {
            int bytesRead = ClientSocket.Receive(receivedPacket, SocketFlags.None);

            if (bytesRead > 0)
            {
                SocketObject.ProcessMessage(receivedPacket);
                // no UI update but fire an event
                MessageProcessed?.Invoke(this, new SomeDataObject());
            }
            else
            {
                throw new Exception("No bytes read");
            }
        }
        catch (Exception ex)
        {
            IsListeningForBytes = false;
            Disconnect();
            Console.WriteLine(ex.Message);
        }
    }
}

发布一些相关代码。。。顺便说一句,您可以使用
任务
您使用的是哪个UI框架?WinForms?Wpf?控制台?Ps;如果你让调用方决定:只需实现一个要引发的事件。很难猜到你想把数据放在哪里,但这里有一个例子,你有一个文本框在表单1中,你想从类1中填充它,然后创建一个以字符串为参数的方法,然后填充文本框。此方法应在Form1类中。然后在课堂上打电话。public fillTextbox(string data){textBox1.Text=data;}然后从类1调用此方法,如果您输入一些代码,我们将能够提供更多帮助。如果我使用您的示例,如何从引发的事件更新GUI?我是否一直在从GUI中查找此事件?这就是我困惑的地方。我会更新答案的。为此,您可能需要深入了解基本的事件处理。试试教程;-)
//so, your UI, can be a window, a form or ... console.
//I'll call your class BytesReceiver
public class FooGUI
{
     BytesReceiver _receiver = new BytesReceiver();

     //somewhere, in some function your listener has started
     void Init()
     {
         //we added an event earlier, now attach a handler.
         //a handler is a function, bound to some signature (as defined by the delegate)
         //which will be executed when the event is triggered.

          //so again; we bind a function to the event, which is invoked when the event is 
          //raised.

          //keep in mind: the Invoke take place on the other thread; so the handler
          //runs on that same thread.

          //there is no magical polling taking place: it's just a 
          //function call (from receiver).

         //note: there are various ways to bind a function: I'll use lambda here
         _receiver.MessageProcessed += (sender,e) =>
         {
             //update GUI here. 
         }

         //since there your while loop waits for a long time
         //there must be some non-blocking operation, presumably on another thread.
         _receiver.StartListening();
     }
}