В практике часто требуется найти решение на тот или иной вопрос, но не всегда ответ очевиден. Вот так же случилось у меня. В работе столкнулся с тем что надо принять данные с СОМ порта, ну что же подумал я, плевое дело. Бросил на форму компонент SerialPort и ListBox, в событии serialPort1_DataReceived задал для listBox1 новый итем с данными из СОМ порта, код выглядел так:
private void Form1_Load(object sender, EventArgs e) { serialPort1.Open(); //открываем порт } private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { listBox1.Items.Add(serialPort1.ReadLine()); //получаем данные }
Все просто до безобразия, но запустив проект я не увидел никаких данных. Написал подобный проект на Borland C++ Builder6, там все работало. После долгих поисков нашол кусок кода для работы с СОМ портом, помоему на www.codeproject.com, который натолкнул на мысль и появилась реализация через Callback посылку данных с порта на ListBox. Код этого метода ниже:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO.Ports; namespace SerrialPortReader { public partial class Form1 : Form { string InputData = String.Empty; delegate void SetTextCallback(string text); //объявляем делегата для Callback метода public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // получаем список СОМ портов системы string[] ports = SerialPort.GetPortNames(); foreach (string port in ports) { comboBox1.Items.Add(port); } } void AddData(string text) { listBox1.Items.Add(text); //отображаем полученные данные } private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { InputData = port.ReadExisting(); if (InputData != String.Empty) { SetText(InputData); } } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (comboBox1.Text != "") { groupBox2.Enabled = true; button1.Enabled = true; } else { groupBox2.Enabled = false; button1.Enabled = false; } } private void button1_Click(object sender, EventArgs e) { if (button1.Text == "Старт") { if (port.IsOpen) port.Close(); #region Задаем параметры порта port.PortName = comboBox1.Text; port.BaudRate = Convert.ToInt32(comboBox2.Text); port.DataBits = Convert.ToInt32(comboBox3.Text); switch (comboBox4.Text) { case "Пробел": port.Parity = Parity.Space; break; case "Чет": port.Parity = Parity.Even; break; case "Нечет": port.Parity = Parity.Odd; break; case "Маркер": port.Parity = Parity.Mark; break; default: port.Parity = Parity.None; break; } switch (comboBox5.Text) { case "2": port.StopBits = StopBits.Two; break; case "1.5": port.StopBits = StopBits.OnePointFive; break; case "Нет": port.StopBits = StopBits.None; break; default: port.StopBits = StopBits.One; break; } switch (comboBox6.Text) { case "Xon/Xoff": port.Handshake = Handshake.XOnXOff; break; case "Аппаратное": port.Handshake = Handshake.RequestToSend; break; default: port.Handshake = Handshake.None; break; } #endregion try { port.Open(); button1.Text = "Стоп"; button2.Enabled = false; } catch { MessageBox.Show("Порт " + port.PortName + " невозможно открыть!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Warning); comboBox1.SelectedText = ""; button1.Text = "Старт"; } } else { if (port.IsOpen) port.Close(); button1.Text = "Старт"; button2.Enabled = true; } } //соответственно сам метод нашего Callback'а private void SetText(string text ) { if (this.listBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.AddData(text); } } //корректно завершаем работу программы private void Form1_FormClosing(object sender, FormClosingEventArgs e) { button1.Text = "Стоп"; Application.DoEvents(); button1_Click(sender, e); Application.DoEvents(); }
Проект программы позволяющий просматривать данные с СОМ порта.