Задать вопрос

С#, не выполняется this.textBox1.AppendText, другой поток?

Добрый день!

Столкнулся с такой проблемой, при срабатывании события элемент формы:
this.textBox1.AppendText(m + Environment.NewLine);

Не делает не чего, точнее не выводит на форму переменную m, хотя при пошаговой проверке она содержит строковое значение, но ее результат не отображается.

Теперь суть работы кода:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;

//делегат для работы с событием
delegate void MessageDelegate();
namespace testGenerator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //получаем все порты доступные в системе
            string[] ports = SerialPort.GetPortNames();
            //очищаем бокс
            comboBox1.Items.Clear();
            //добавляем в comboBox  все найденные порты для выбора
            comboBox1.Items.AddRange(ports);
        }
//функция вывода сообщения полученного из COM  порта
public void writeTB1(string m)
        {
            this.textBox1.AppendText(m + Environment.NewLine);
        }
 //инициализация нужного порта
        private void button2_Click(object sender, EventArgs e)
        {
            var port = new MySerialPort();
            port.Open(comboBox1.SelectedItem.ToString());
        }

//тут пойдет взаимодейсвие с com портом
    public class MySerialPort : SerialPort
    {
        private int _stepIndex;
        private bool _startRead;

        public MySerialPort()
            :base()
        {

            //base.PortName = port;
            base.BaudRate = 9600;
            base.DataBits = 8;
            base.StopBits = StopBits.One;
            base.ReadTimeout = 1000;

            //Подписываемся на событие прихода данных в com  порт
            base.DataReceived += new SerialDataReceivedEventHandler(MySerialPort_DataReceived);
 
        }

        public void Open(string portName)
        {
            if (base.IsOpen)
            {
                base.Close();
            }
            base.PortName = portName;
            base.Open();
        }
//событие прихода данных в буфер com порта
        void MySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            EventAnswer eventAnswer = new EventAnswer();
            AnswerCsw answerCsw = new AnswerCsw();
            eventAnswer.Send += new MessageDelegate(answerCsw.AnswerEvent);
            var port = (SerialPort)sender;
            try
            {
                int buferSize = port.BytesToRead;
                byte[] _buffer = new byte[buferSize];
                _stepIndex = 0;
                for ( int i=0; i < buferSize; i++)
                {
                    byte bufferReadBt = (byte)port.ReadByte();
                    _buffer[_stepIndex] = bufferReadBt;
                    ++_stepIndex;
                    char rbt = Convert.ToChar(bufferReadBt);
                    //Запись полученного текста в переменную text класса answer
                    AnswerCsw.AnswerText += Convert.ToString(rbt);
//если мы собрали все байты из буфера COM порта то вызываем событие DoEvent();
                    if (_stepIndex == buferSize)
                    {
                        eventAnswer.DoEvent();
                        AnswerCsw.AnswerText = null;
                    }
                }
            }
            catch { }
        }
    }

    //класс для ответа
    class AnswerCsw : Form1
    {
//сюда складываются конвертированные байтики из порта
        public static string AnswerText;
//ну и собственно по приходу события сама функция которая должна отправить собранную
//строку в необходимый мне textbox
        public void AnswerEvent()
        {
            writeTB1(AnswerText);
        }

    }
//событие для отправки ответа, когда все байты уложенны в AnswerText
    class EventAnswer
    {
        public event MessageDelegate Send;
        public void DoEvent()
        {
            Send();
        }
    }
}


Не могу понять где лыжи не едут.
Инициализирую порт для прослушки.
Отправляю команду в ком порт уже с другой софтины событие прихода данных срабатывает.
Дальше все проходит идеально все байты конвертируются и по очереди прихода складываются в AnswerText:
public static string AnswerText;
Как только дошел до последнего индекса вызывается событие:
if (_stepIndex == buferSize)
                    {
                        eventAnswer.DoEvent();
                        AnswerCsw.AnswerText = null;
                    }


Вызывается его обработчик:

class EventAnswer
    {
        public event MessageDelegate Send;
        public void DoEvent()
        {
            Send();
        }
    }


так как подписан на срабатывание события Send();

eventAnswer.Send += new MessageDelegate(answerCsw.AnswerEvent);


Cледом выполняется функция public void AnswerEvent() :

class AnswerCsw : Form1
    {
//сюда складываются конвертированные байтики из порта
        public static string AnswerText;
//ну и собственно по приходу события сама функция которая должна отправить собранную
//строку в необходимый мне textbox
        public void AnswerEvent()
        {
            writeTB1(AnswerText);
        }
    }


Которая в свою очередь выполняет код:

public void writeTB1(string m)
        {
            this.textBox1.AppendText(m + Environment.NewLine);
        }


Но не чего не происходит, на форме остается по прежнему белый лист, хотя повторюсь при пошаговой проверке переменная m содержит предположим текст "CC;"

Где я повернул не туда? :)

Буду признателен за любые ответы, нагоняи за не правильную работу с кодом приветствуются :)
  • Вопрос задан
  • 1395 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
@vitvov
У вас плохая архитектура приложения.
Поясню, а дальше дам пример.
1) MySerialPort должен генерировать события.
2) Главное окно, где создан этот обьект, должно подписатся на событие. (В принципе, подписатся может кто угодно, но в вашем случае именно главное окно)
3) При получении нужных данных, класс MySerialPort должен послать событие.
4) Главное окно получило данные и отобразило их на экран.

Теперь, как это делается:
В отдельном файле
DataCompleadEventArgs.cs
описываете класс события:
namespace MyNamespace
{ 
      public delegate void DataCompleadEventHandler(object sender, DataCompleadEventArgs e);
      public class DataCompleadEventArgs : EventArgs
      {
            private string _data;
 	    public DeviceEventArgs (string data)
 	    {
       	          _data; = data
 	    }
 	    public string Data
 	    {
                  get { return _data; }
 	    }
      }
}


далее в классе
MySerialPort
пишите следующее:
public class MySerialPort : SerialPort
{
      //  ваш код ...
      //  обьявляете событие
      public event DataCompleadEventHandler DataComplead;
      //  описываете функцию, чтоб слать событие наружу
      private void OnDataComplead(string message)
      {
            if (DataComplead != null) 
            {
                 DataComplead(this, new DataCompleadEventArgs(message));
            }
      }

      public MySerialPort() :base()
      {
            // ваш код ...
            base.DataReceived += new SerialDataReceivedEventHandler(MySerialPort_DataReceived);
      }

      void MySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
            // то, что тут было написано не нужно !!!
            var port = (SerialPort)sender;
            try
            {
                  // ваш код ...
                  var message = Convert.ToString(rbt);
                  if (_stepIndex == buferSize)
                  {
                        // шлём событие наружу 
                        OnDataComplead(message );
                  }
            }
            catch { }
      }
}


И самое главное, в основном окне:
public partial class Form1 : Form
{
      public Form1()
      {
            InitializeComponent();
            // ...
      }

      private void button2_Click(object sender, EventArgs e)
      {
            var port = new MySerialPort();
            // подписиваемся на событие
            port.DataComplead += OnDataCompleated;
            port.Open(comboBox1.SelectedItem.ToString());
      }

      private void OnDataCompleated(object sender, DataCompleadEventArgs e)
      {
            // получаем нужные данные
            var message = e.Data;
            writeTB1(message);
      }
}


Вот и всё.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Neuroware
@Neuroware
Программист в свободное от работы время
можно попробовать обернуть в MethodInvoker, мне он помогает в 99% случаев

BeginInvoke(new MethodInvoker(delegate
{
textBox1.AppendText("Программа завершила свою работу!");
//здесь может быть любой код
}));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы