我在一个关于串口操作的项目里,利用一个窗体来对串口进行读写操作。
config.cs窗体用来设置参数及收发指令。
Comm.cs类用来执行收发工作。
我的想法是当串口接收到数据后,config.cs窗体上自动弹出一个MessageBox。我采用了委托与事件方式。
代码如下,现在的问题是:在config.cs中设置串口参数及发送指令都正常,但是接收就不行了,用断点监控Comm.cs文件,可以确定串口是有接收有内容,但就是无法反馈到config.cs窗体上并自动弹出MessageBox.不好意思,初学c#,对事件和委托感到很糊涂。总找不出问题出在哪里。还望高手们指点下迷津啊。
config.cs窗体代码:
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;namespace SerialPort_WR
{
    public partial class Config : Form
    {
        private Comm comm;
        public string spName;//serialPort.PortName
        public int spBaudRate;//serialPort.BaudRate
        public System.IO.Ports.StopBits spStopBits;//serialPort.StopBits;
        public int spDataBits;//serialPort.DataBits
        public System.IO.Ports.Handshake spHandShake;//serialPort.HandShake
        public System.IO.Ports.Parity spParity;//serialPort.Parity;        public Config()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            PortSetupInit();
        }        public void PortSetupInit()
        {   
            //扫描所有串口
            foreach (string P in System.IO.Ports.SerialPort.GetPortNames())
            {
                cB_PortName.Items.Add(P);
            }
            cB_PortName.SelectedIndex = 1;
            cB_BaudRate.SelectedIndex = 9;//波特率
            cB_DataBits.SelectedIndex = 3;//数据位
            cB_Handshake.SelectedIndex = 2;//流控制
            cB_Parity.SelectedIndex = 0;//校验位
            cB_StopBits.SelectedIndex = 0;//停止位
            cB_SchTak.SelectedIndex = 0;//查询时间
            //serialPort1.RtsEnable = true;
            //serialPort1.Encoding = System.Text.Encoding.GetEncoding("GB2312");//指定字符集,使之能发送中文
        }        void comm_HaveDataReady(string RevCmd, String RevData)//这里设置了断点,总是无法执行这一行。问题可能出在这里。
        {
            this.BeginInvoke(new Comm.DataEventHandler(DataReady), new object[]{RevCmd,RevData});
        }        void DataReady(string RevCmd, String RevData)
        {
            MessageBox.Show(RevCmd, RevData);
        }        private void ConfigSave_Click(object sender, EventArgs e)
        {
            if (comm != null)
            {
                if (comm.IsOpen())
                {
                    comm.Close();
                }
                else
                {
                    comm.Open();
                }
            }
            else
            {
                SPSetup();
                comm = new Comm(spName, spBaudRate, spParity, spDataBits, spStopBits, spHandShake);
                comm.HaveDataReady += new Comm.DataEventHandler(comm_HaveDataReady);
                comm.Open();
                ConfigSave.Text = "关闭串口";
            }        }        public void SPSetup()
        {
            spName = cB_PortName.Text;
            spBaudRate = Convert.ToInt32(cB_BaudRate.Text);
            spDataBits = Convert.ToInt16(cB_DataBits.Text);
            switch (cB_StopBits.SelectedItem.ToString())//设置停止位
            {
                case "1":
                    spStopBits = System.IO.Ports.StopBits.One;
                    break;
                case "1.5":
                    spStopBits = System.IO.Ports.StopBits.OnePointFive;
                    break;
                case "2":
                    spStopBits = System.IO.Ports.StopBits.Two;
                    break;
            }
            switch (cB_Handshake.SelectedItem.ToString())//设置流控制
            {
                case "HARDWARE":
                    spHandShake = System.IO.Ports.Handshake.RequestToSend;
                    break;
                case "SOFTWARE":
                    spHandShake = System.IO.Ports.Handshake.XOnXOff;
                    break;
                case "NONE":
                    spHandShake = System.IO.Ports.Handshake.None;
                    break;
                case "Custom":
                    spHandShake = System.IO.Ports.Handshake.RequestToSendXOnXOff;
                    break;
            }
            switch (cB_Parity.SelectedItem.ToString())//设置校验位
            {
                case "None":
                    spParity = System.IO.Ports.Parity.None;
                    break;
                case "Odd":
                    spParity = System.IO.Ports.Parity.Odd;
                    break;
                case "Even":
                    spParity = System.IO.Ports.Parity.Even;
                    break;
                case "Mark":
                    spParity = System.IO.Ports.Parity.Mark;
                    break;
                case "Space":
                    spParity = System.IO.Ports.Parity.Space;
                    break;
            }
        }        private void bT_Clear_Click(object sender, EventArgs e)
        {
            //tB_Receive.Clear();
            //Comm com = new Comm(spName, spBaudRate, spParity, spDataBits, spStopBits, spHandShake);            tB_Receive.Text += comm.s2;
        }        private void tB_Receive_TextChanged(object sender, System.EventArgs e)
        {
            if (tB_Receive.Text.Length > 0)
            {
                tB_Receive.Select(tB_Receive.Text.Length - 1, 0);   // 如果有換行的数据时,会在最后一行产生空行。
                tB_Receive.ScrollToCaret();
            }
        }        public void bT_SendMsg_Click(object sender, EventArgs e)
        {
            comm.SendMsg(tB_PhoneNo.Text, tB_Msg.Text);
        }
        private void Delay(int mm)
        {
            DateTime current = DateTime.Now;            while (current.AddMilliseconds(mm) > DateTime.Now)
            {
                Application.DoEvents();
            }
            return;
        }        private void Config_Resize(object sender, EventArgs e)
        {
           this.FormBorderStyle =System.Windows.Forms.FormBorderStyle.None;
        }
    }Comm.cs文件代码:using System.Text;
using System;
using System.Threading;
using System.IO;
using System.IO.Ports;
using System.Windows.Forms;public class Comm
{
    private SerialPort port;
    private byte[] readcache;
    private int idx;
    public string SendOK;
    public string s2;
    public string s3;    public delegate void DataEventHandler(string RevCmd, string RevData);
    public event DataEventHandler HaveDataReady;    public Comm(string spName, int spBaudRate, Parity spParity, int spDataBits, StopBits spStopBits, Handshake spHandShake)
    {
        port = new SerialPort(spName, spBaudRate, spParity, spDataBits, spStopBits);
        port.Handshake = spHandShake;
        port.ReadTimeout = 500;
        port.WriteTimeout = 500;
        port.ReadBufferSize = 1024;
        port.ReceivedBytesThreshold = 1;        port.DataReceived += new SerialDataReceivedEventHandler(portDataReceived);
        readcache = new byte[256];
        idx = 0;
    }    public bool IsOpen()
    {
        return port.IsOpen;
    }
    public void Open()
    {
        port.Open();
    }
    public void Close()
    {
        port.Close();
    }    public void portDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            byte inputData = 0;
            while ((port.BytesToRead > 0))
            {
                inputData = (byte)port.ReadByte();
                
                if (inputData.Equals(0xa))
                {
                    idx = 0;
                }
                else if (inputData.Equals(0xd))
                {
                    byte[] b = new byte[idx];
                    Array.Copy(readcache, b, idx);
                    s2 = Encoding.ASCII.GetString(b);
                    st(s2);
                    idx = 0;                }
                else
                {
                    readcache[idx] = inputData;
                    idx++;
                    idx %= 1024;
                }
            }
        }
        catch
        {
        }        
    }
    public void st(string s2)
    {
        s3 = s2;
    }    public void SendMsg(string phone, string msg)
    {
       port.WriteLine(phone);
       port.WriteLine(msg);    }    private void Delay(int mm)
    {
        DateTime current = DateTime.Now;        while (current.AddMilliseconds(mm) > DateTime.Now)
        {
            Application.DoEvents();
        }
        return;
    }}

解决方案 »

  1.   

    在Comm类里接收信息代码处加上抛起事件if(HaveDataReady!=null)
       HaveDataReady(RevCmd,RevData);
      

  2.   

    我在在Comm类里接收信息代码处加上你说的这行:
    if(HaveDataReady!=null)
       HaveDataReady(RevCmd,RevData);
    但提示错误
    “当前上下文中不存在名称“RevData””
    “当前上下文中不存在名称“RevCmd””
    这个RevCmd和RevData是在Config窗体的void comm_HaveDataReady(string RevCmd, string RevData)里定义的,应该如何处理才能在Comm类里能认到它呢?
      

  3.   


    RevCmd和RevData换成你实际的值
      

  4.   

    if(HaveDataReady!=null)
       HaveDataReady(RevCmd,RevData);
    不要一个字不差的copy好不好,你要传入的是这两个参数,你在接受事件中,对这两个值赋值就行了
    比如 
    HaveDataReady("aa","bbb")
      

  5.   

    string RevCmd="RevCmd的值";
    string RevData="RevData的值";
      

  6.   

    谢谢大家。问题解决了。现在对委托和事件有了个初步了解了。只有100分,三位都回答正确,我看这样分配好不好:gxingmin 40分,其余两位各30分。如果认为不妥,我再送分。再次感谢!