正在从SerialDataReceivedEventHandler写入文本框控件
本文关键字:文本 控件 SerialDataReceivedEventHandler | 更新日期: 2023-09-27 18:00:32
我敢肯定只有我自己做得不对。
我有一个Form1
,它有一个按钮,onclick可以调用我的serialConn.cs中名为connect()
的方法。
public static bool connect(string comPort) {
BTserial = new SerialPort(comPort, 9600, Parity.None, 8, StopBits.One);
BTserial.Open();
if (BTserial.IsOpen) {
BTserial.DataReceived += new SerialDataReceivedEventHandler(DataReceivedEvent);
return true;
} else {
return false;
}
}
private static void DataReceivedEvent(object sender, SerialDataReceivedEventArgs e) {
Debug.WriteLine("Data Incomming!");
// Check if Chars are received
if (e.EventType == SerialData.Chars) {
Debug.WriteLine("Chars!");
// Create new buffer
byte[] ReadBuffer = new byte[BTserial.BytesToRead];
// Read bytes from buffer
BTserial.Read(ReadBuffer, 0, ReadBuffer.Length);
BTserial.DiscardInBuffer();
// Encode to string
string data = bytesToString(ReadBuffer);
ReadBuffer = null;
data = null;
}
}
这一切都很好,但当收到数据时,我希望它打印在我的Form1
中的TextBox
控制器中。。但由于我的DataReceivedEvent()
是static
(我想我必须是?),我什么都不能访问?那么,解决这一问题的最佳方式是什么呢?
您需要将Form实例传递到此连接方法(从按钮的事件处理程序):
public class Form1 : Form {
public void Button1_Click(object sender, EventArgs e) {
serialConn.connect("the com port here", this);
}
// ... etc ...
}
串行时Conn:
public static bool connect(string comPort, Form1 whichForm) {
然后,您可以使用lambda函数并关闭其中的"whichForm"引用,如下所示:
但此外,您应该确保您实际上没有从主线程之外的另一个线程修改GUI——这是非常可能的,因为SerialPort类的性质很可能会从另一个后台线程引发事件——因此。Invoke(一些其他lambda),它封送该特定操作,该操作又在主线程上执行。
MSDN明确指出:http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx
从SerialPort对象接收数据时,在辅助线程上引发DataReceived事件。由于此事件是在辅助线程而非主线程上引发的,因此尝试修改主线程中的某些元素(如UI元素)可能会引发线程异常。如果有必要修改主Form或Control中的元素,请使用Invoke将更改请求发回,Invoke将在正确的线程上完成工作。
public static bool connect(string comPort, Form1 whichForm) {
BTserial = new SerialPort(comPort, 9600, Parity.None, 8, StopBits.One);
BTserial.Open();
if (BTserial.IsOpen) {
BTserial.DataReceived += (sender, e) => {
Debug.WriteLine("Data Incomming!");
// Check if Chars are received
if (e.EventType == SerialData.Chars) {
Debug.WriteLine("Chars!");
// Create new buffer
byte[] ReadBuffer = new byte[BTserial.BytesToRead];
// Read bytes from buffer
BTserial.Read(ReadBuffer, 0, ReadBuffer.Length);
BTserial.DiscardInBuffer();
// Encode to string
string data = bytesToString(ReadBuffer);
Action toBeRunOnGuiThread = () => whichForm.theTextBox.Text = data;
// to guard yourself from all evil
// you could check to see if it is needed to
if (whichForm.InvokeRequired)
// marshal the call to the action all the way to the GUI thread
whichForm.Invoke(toBeRunOnGuiThread);
else
// or, if we ARE on the GUI thread already, just call it from this thread
toBeRunOnGuiThread();
ReadBuffer = null;
data = null;
}
};
return true;
} else {
return false;
}
}