none
スクロールバーが不本意に動いてしまう事について RRS feed

  • 質問

  •  

    C#プログラム初心者です。どなたかのご協力が得られれば幸いです。

     

    入門としてTeraTerm的なアプリを作成しようと思っています。

     

    シリアルポートから1バイトずつ受信した文字列をTextBox表示していくことを目的としています。

     

     1        //シリアルポート受信イベント
     2        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
     3        {
     4            string result;
     5            Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");

     6            rcvData = new byte[1];
     7            result = "";

     8            rcvData[0] = (byte)serialPort1.ReadByte();                  //入力バッファから同期で1バイト取得する。
     9            if (rcvData[0] == 0x0d)
    10            {
    11                result = "\r\n";                                        //キャリッジリターン/ラインフィード
    12            }
    13            else
    14            {
    15                result = sjisEnc.GetString(rcvData);                    //文字に変換
    16            }
    17            captureResult.Text += result;                               //TextBoxに受信した文字を表示する。
    18            captureResult.SelectionStart = captureResult.TextLength;    //カレット位置を次文字入力位置へ移動する。
    19            captureResult.ScrollToCaret();                              //コントロールの内容を現在のカレット位置までスクロールする。
    20            if (captureResult.TextLength > captureResult.MaxLength)
    21            {
    22                captureResult.Text.Remove(0, 1);
    23            }
    24        }

    上記のようにプログラムしたのですが、連続的に受信を行うと、テキストボックスがちらつきを起こしてしまいました。

     

    17行目で受信文字を表示し、18行目でカレットの位置を移動、19行目でスクロールの移動を行っていますが、

    どうやら、受信イベントが立つたびにスクロールがテキストBoxの最上位まで移動してしまって、その度に、

    19行目のスクロール移動が走り、ちらつきが起きてしまっているようです。

     

    何かよい方法があればご教授下さい。よろしくお願いします。

    2008年2月7日 0:33

回答

  • まず、DataReceived イベントで TextBox に触ってはいけません。

    SerialPort.DataReceived イベント (System.IO.Ports)

    解説にあるとおり、コントロールへの操作処理については Control::Invoke などを使用してメインスレッドで実行させる必要があります。

     

    さて本題のちらつきの方ですが、Text プロパティだと先頭から書き直しになるので一旦上に行くってことになるわけで、単純に末尾に追加していくだけなら AppendText メソッドを使用すればいいでしょう。

    2008年2月7日 2:08

すべての返信

  • まず、DataReceived イベントで TextBox に触ってはいけません。

    SerialPort.DataReceived イベント (System.IO.Ports)

    解説にあるとおり、コントロールへの操作処理については Control::Invoke などを使用してメインスレッドで実行させる必要があります。

     

    さて本題のちらつきの方ですが、Text プロパティだと先頭から書き直しになるので一旦上に行くってことになるわけで、単純に末尾に追加していくだけなら AppendText メソッドを使用すればいいでしょう。

    2008年2月7日 2:08
  • 的確な解答、本当にありがとうございます。

     

    > まず、DataReceived イベントで TextBox に触ってはいけません。

    > SerialPort.DataReceived イベント (System.IO.Ports)

    > 解説にあるとおり、コントロールへの操作処理については Control::Invoke などを使用してメインスレッドで実行させる必要があります。

     

    イベント処理内では行ってはいけない処理だったのですね、勉強になります。

    ソースに反映してみます。

     

    > さて本題のちらつきの方ですが、Text プロパティだと先頭から書き直しになるので一旦上に行くってことになるわけで、単純に末尾に追加していくだけなら AppendText メソッドを使用すればいいでしょう。

     

    さしあたり、Invoke等でメインスレッドに処理を移行する前に、AppenndTextを使用したところ問題の件、解決しました。

    ありがとう御座います。

     

    今後も初心者ならではの質問を投稿するかもしれませんが、その時はよろしくお願いします。

    2008年2月7日 2:31