我在一个关于串口操作的项目里,利用一个窗体来对串口进行读写操作。
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;
}}
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;
}}
HaveDataReady(RevCmd,RevData);
if(HaveDataReady!=null)
HaveDataReady(RevCmd,RevData);
但提示错误
“当前上下文中不存在名称“RevData””
“当前上下文中不存在名称“RevCmd””
这个RevCmd和RevData是在Config窗体的void comm_HaveDataReady(string RevCmd, string RevData)里定义的,应该如何处理才能在Comm类里能认到它呢?
RevCmd和RevData换成你实际的值
HaveDataReady(RevCmd,RevData);
不要一个字不差的copy好不好,你要传入的是这两个参数,你在接受事件中,对这两个值赋值就行了
比如
HaveDataReady("aa","bbb")
string RevData="RevData的值";