C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: コントロール配列にデリゲートを使用して値を代入する方法


(過去ログ 15 を表示中)

[トピック内 2 記事 (1 - 2 表示)]  << 0 >>

■5071 / inTopicNo.1)  コントロール配列にデリゲートを使用して値を代入する方法
  
□投稿者/ アーラン (9回)-(2007/07/03(Tue) 17:32:22)

分類:[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の記述方法がわかりません。

配列でない代入のデリゲートのサンプルは見つかるのですが,コントロール配列の場合がよくわかりません。よろしくお願いいたします。

引用返信 編集キー/
■5073 / inTopicNo.2)  Re[1]: コントロール配列にデリゲートを使用して値を代入する方法
□投稿者/ 黒龍 (79回)-(2007/07/03(Tue) 17:44:55)
> 配列でない代入のデリゲートのサンプルは見つかるのですが,コントロール配列の場合がよくわかりません。よろしくお願いいたします。
>
コントロール配列のサンプルもすぐ見つかるように思います。
ずばりな答えを捜し求めるのではなく考えてコーディングしないと問題発生時に対応できなくなりそうに思いますが・・・。

> スレッド・セーフなコードを作成するにはデリゲートを使用する必要があるのですが,この3個のコントロール配列に値を代入するdelegateの記述方法がわかりません。
ここもなぜそういいきれるのでしょうか?理解したうえであれば提示されたコードの内容も違ってくる気がします。

がんばってみてください。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -