C# 从C中的类更新GUI的正确方法#
我正在寻找一种方法,从一个我希望独立且不依赖GUI的类更新GUI。它是一个由侦听器和客户端组成的网络类。此类可以连接然后发送/接收数据。我希望这些数据能够使用GUI显示,但在类本身中没有任何与GUI相关的代码 简言之,网络类只知道自己。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)
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();
}
}