1

私の問題は、UI スレッドとは別のスレッドの TextBox.text を大量に変更することです。このような:

string bufferSerial;
.
.
.
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    bufferSerial += serialPort1.ReadLine();
    TextBox1.text = bufferSerial;
    TextBox2.text = bufferSerial;
    TextBox3.text = bufferSerial;
    TextBox4.text = bufferSerial;
    TextBox5.text = bufferSerial;
    TextBox6.text = bufferSerial;
    TextBox7.text = bufferSerial;
.
.
.
.
.
.
    TextBoxN.text = bufferSerial;
}

これを実行しようとすると、エラーが発生します: コントロール 'textBox1' は、作成されたスレッド以外のスレッドからアクセスされました。

単一の TextBox を変更するには、次のソリューションを使用できます。

delegate void SetTextCallback(string text);

private void SetText(string text)
{
  // InvokeRequired required compares the thread ID of the
  // calling thread to the thread ID of the creating thread.
  // If these threads are different, it returns true.
  if (this.textBox1.InvokeRequired)
  { 
    SetTextCallback d = new SetTextCallback(SetText);
    this.Invoke(d, new object[] { text });
  }
  else
  {
    this.textBox1.Text = text;
  }
}

次に、次のように関数を呼び出します。

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
  bufferSerial += serialPort1.ReadLine();
  SetText(bufferSerial);
}

しかし、多くの BoxText を変更する必要がある場合は、それぞれに対して 1 つの関数を作成する必要がありますか?

ご協力ありがとう御座います!よろしくお願いします。

4

1 に答える 1

0

いいえ、すべてのテキスト ボックスを変更する 1 つのメソッドを作成し、それを呼び出します。

// We assume this will always be called from a non-UI thread...
private void HandleDataReceived(object sender, SerialDataReceivedEventArgs e)
{
    bufferSerial += serialPort1.ReadLine();
    Action<string> d = SetAllTextBoxes;
    Invoke(d, bufferSerial);
}

private void SetAllTextBoxes(string text)
{
    textBox1.Text = text;
    textBox2.Text = text;
    textBox3.Text = text;
    textBox4.Text = text;
    ...
}

理想的には、次のように書き直すことができるように、コレクションにテキストボックスを用意します。

private void SetAllTextBoxes(string text)
{
    foreach (var textBox in textBoxes)
    {
        textBox.Text = text;
    }
}
于 2013-03-02T14:51:26.173 に答える