次のコードがあり、データをポートから読み取ってテキストボックスに表示する必要があります。この目的でDataReceivedイベントハンドラーを使用していますが、このデータをテキストボックスに表示する方法がわかりません。さまざまな情報源から、これにはInvokeメソッドを使用する必要があることを学びましたが、その使用方法がわかりません。提案をお願いします...
private void Form1_Load(object sender, EventArgs e)
{
//SerialPort mySerialPort = new SerialPort("COM3");
mySerialPort.PortName = "COM3";
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived);
mySerialPort.Open();
}
private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string s= sp.ReadExisting();
// next i want to display the data in s in a textbox. textbox1.text=s gives a cross thread exception
}
private void button1_Click(object sender, EventArgs e)
{
mySerialPort.WriteLine("AT+CMGL=\"ALL\"");
}
MSDNには、他のスレッドからの制御メソッドとプロパティの使用に関する例を含む、優れた article が含まれています。
つまり、必要なのは、テキストボックスのText
プロパティを指定された文字列で設定するデリゲートメソッドです。次に、TextBox.Invoke()
メソッドを介して、mySerialPort_DataReceived
ハンドラー内からそのデリゲートを呼び出します。このようなもの:
public delegate void AddDataDelegate(String myString);
public AddDataDelegate myDelegate;
private void Form1_Load(object sender, EventArgs e)
{
//...
this.myDelegate = new AddDataDelegate(AddDataMethod);
}
public void AddDataMethod(String myString)
{
textbox1.AppendText(myString);
}
private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string s= sp.ReadExisting();
textbox1.Invoke(this.myDelegate, new Object[] {s});
}
これを試してください(私のために働きます):
private delegate void UpdateUiTextDelegate(string text);
private void Receive(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (mySerialPort.IsOpen)
{
RxString = mySerialPort.ReadLine();
Dispatcher.Invoke(DispatcherPriority.Send, new UpdateUiTextDelegate(DisplayText), RxString);
}
}
private void DisplayText(string RxString)
{
myTextBox.Text = RxString;
}
USBCOMポート用のGUI「フォーム」を作成しています。これは、「クロススレッド」エラーを取得せずにウィンドウにデータを送信する方法です。
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string inData = serialPort1.ReadLine(); // ReadLine includes the + "\n"
displayToWindow(inData);
}
private void displayToWindow(string inData)
{
BeginInvoke(new EventHandler(delegate
{
richTextBox1.AppendText(inData);
richTextBox1.ScrollToCaret();
}));
}