|
分類:[C# (Windows)]
開発環境: Windows XP
開発言語: Visual C# 2005
●質問の要点
コントロール配列にデリゲートを使用して値を代入する方法の記述を教えていただけるようにお願いいたします。
●サンプル・コード
フォームにTextBoxを3個,SerialPortを1個配置してあります。
TextBoxは配列としてアクセスできるようにしてあります。
サンプル・コードは以下のとおりです。
================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace serial_delegate {
public partial class Form1 : Form {
const int recvBuffMax = 4096;
byte[] recvBuff = new byte[recvBuffMax];
int recvCount; // 受信カウンタ
private System.Windows.Forms.TextBox[] textBoxArray = new System.Windows.Forms.TextBox[3];
int counter;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
int n = 1;
for (int i = 0; i < 3; i++) {
textBoxArray[i] = (TextBox)Controls["textBox" + n.ToString()];
n++;
};
serialPort1.Open();
Form1.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
serialPort1.Close();
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) {
// recvCountが必ず1文字になるように送信側でゆっくりキーボードをタイプしています。
recvCount = serialPort1.Read(recvBuff, 0, recvBuffMax);
textBoxArray[counter].Text = "" + (char)recvBuff[0]; // string形に変換
counter++;
counter = counter % 3;
}
}
}
================================================================
● サンプル・コードの動作の詳細
シリアルで『ABC』を受信して"A","B","C"をそれぞれTextBox1,2,3に代入します。
送信側は『A』『B』『C』とゆっくりと入力する前提で作ってあります。
ここで,
Form1.CheckForIllegalCrossThreadCalls = false;
と記述すると送信側から『A』を押したときに"A"がtextBox1に入ります。次に『B』を押すと"B"がtextBox2に入ります。『C』を押すと"C"がtextBox3に入ります。
ここをコメント・アウトにすると
// Form1.CheckForIllegalCrossThreadCalls = false;
この代入が
textBoxArray[counter].Text = "" + (char)recvBuff[0];
=====================================================================
System.InvalidOperationException はハンドルされませんでした。
Message="有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'textBox1' がアクセスされました。"
Source="System.Windows.Forms"
StackTrace:
場所 System.Windows.Forms.Control.get_Handle()
場所 System.Windows.Forms.Control.set_WindowText(String value)
場所 System.Windows.Forms.TextBoxBase.set_WindowText(String value)
場所 System.Windows.Forms.Control.set_Text(String value)
場所 System.Windows.Forms.TextBoxBase.set_Text(String value)
場所 System.Windows.Forms.TextBox.set_Text(String value)
場所 serial_delegate.Form1.serialPort1_DataReceived(Object sender, SerialDataReceivedEventArgs e) 場所 C:\Documents and Settings\xxxxxx\My Documents\Visual Studio 2005\Projects\serial-delegate\Form1.cs:行 42
場所 System.IO.Ports.SerialPort.CatchReceivedEvents(Object src, SerialDataReceivedEventArgs e)
場所 System.IO.Ports.SerialStream.EventLoopRunner.CallReceiveEvents(Object state)
場所 System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
場所 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
=====================================================================
のエラーになります。
スレッド・セーフなコードを作成するにはデリゲートを使用する必要があるのですが,この3個のコントロール配列に値を代入するdelegateの記述方法がわかりません。
配列でない代入のデリゲートのサンプルは見つかるのですが,コントロール配列の場合がよくわかりません。よろしくお願いいたします。
|