在文本框中显示来自串行端口的实时值,并能够使用 C# 在 Windows 表单中单击另一个按钮
Display real time values from a Serial Port in Textboxes and be able to click another button in Windows form using C#
我正在使用 Visual Studio 2015 Community 并使用 C# 进行编码。
我从串行端口接收到一个字符串。然后我需要从中显示 12 个子字符串,并在 12 个不同的文本框中实时显示它们。
只有在我创建的 Windows 表单中单击加载按钮时才会显示这些值。
直到我使用了一个时间间隔为 2 秒的计时器,我才能够做到。
所以,现在我在文本框中获得了实时值,但是我无法单击表单中的其他按钮。
我对此深陷其中。有什么方法可以在表单中加载实时值,并且仍然可以点击其他按钮吗?
到目前为止,这是我的代码:
using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Diagnostics;
namespace Taskcontinue
{
public partial class Form1 : Form
{// defining a serial port in the code
SerialPort myport = new SerialPort();
int flag = 0;
string input = " "; public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
//detect a * in string and then start extracting the sub-string as defined
private void Skeleton()
{
{
if(myport.IsOpen)
{
myport.Close();
}
myport.BaudRate = 9600;
myport.PortName = "COM9";
myport.Parity = Parity.None;
myport.DataBits = 8;
myport.Open();
{
while (flag == 0)
{
input = "";
char data = Convert.ToChar(myport.ReadChar());
if (data == '*')
{
flag = 1;
input += data;
Debug.WriteLine("star is detected::");
}
}
if (flag == 1)
{
// Debug.WriteLine("WE RE INSIDE FLAG::");
for (int i = 0; i <= 129; i++)
{
// Debug.WriteLine("WE RE IN FOR LOOP::");
input += Convert.ToChar(myport.ReadChar());
}
realvalues();
flag = 0;
}
Debug.WriteLine(input);
}
}
}
//this is the button which on clicking should display the values in text boxes
private void load_values_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void myport_DataReceived(objectsender,SerialDataReceivedEventArgs e)
{
string data = Convert.ToChar(myport.ReadChar()).ToString();
}
//extracting substring from the string from serial port
private void realvalues()
{
tb1.Text = input.Substring(4, 7);
tb2.Text = input.Substring(14, 7);
tb3.Text = input.Substring(24, 7);
tb4.Text = input.Substring(34, 7);
tb5.Text = input.Substring(44, 7);
tb6.Text = input.Substring(54, 7);
tb7.Text = input.Substring(64, 7);
tb8.Text = input.Substring(75, 7);
tb9.Text = input.Substring(86, 7);
tb10.Text = input.Substring(97, 7);
tb11.Text = input.Substring(108, 7);
tb12.Text = input.Substring(123, 7);
}
private void timer1_Tick(object sender, EventArgs e)//timer tick event
{
timer1.Stop();
timer1.Start();
Skeleton();
}
}
}
在你的问题中:“有什么方法可以在表单中加载实时值”,我将按字面意思 real time。
您已经使用了 DataReceived
活动。这个可以用来显示数据。您每 2 秒打开和关闭一次端口。除非有特殊且不可避免的原因,否则您可以在 Form
加载时打开它(或制作一个连接按钮)并保持打开状态。
由于您的数据将在另一个线程中读取,因此您需要使用 BeginInvoke
将其推送到您的盒子中。
public partial class Form1 : Form
{
// You will need these delegate to display your data from the other thread
delegate void del(string data);
del MyDelegate;
SerialPort port;
public Form1()
{
InitializeComponent();
// here you create your delegate that will display your data in the textboxes
MyDelegate = new del(realvalues);
}
private void Form1_Load(object sender, EventArgs e)
{
try
{ // open your port once
port = new SerialPort();
port.PortName = "COM9";
port.BaudRate = 9600;
port.Parity = Parity.None;
port.DataBits = 8;
port.Open();
port.DataReceived += port_DataReceived;
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
private void realvalues()
{
tb1.Text = input.Substring(4, 7);
tb2.Text = input.Substring(14, 7);
tb3.Text = input.Substring(24, 7);
tb4.Text = input.Substring(34, 7);
tb5.Text = input.Substring(44, 7);
tb6.Text = input.Substring(54, 7);
tb7.Text = input.Substring(64, 7);
tb8.Text = input.Substring(75, 7);
tb9.Text = input.Substring(86, 7);
tb10.Text = input.Substring(97, 7);
tb11.Text = input.Substring(108, 7);
tb12.Text = input.Substring(123, 7);
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{ // read the data that has arrived
String s = port.ReadLine();
// call here your Skeleton method and pass the entire data string
string input = Skeleton(s);
// now give the input string to the display method
this.BeginInvoke(MyDelegate, s);
}
private string Skeleton(string portOutput)
{
string input = "";
// parse here through your received string with your algorithm
// and return the constructed input string
return input;
}
}
这应该会实时显示值并让您的 GUI 响应。
如果您仍然真的想要一个额外的 LOAD 按钮 来限制您的实时
写信给我,我编辑我的答案。
有关从其他线程更新 GUI 的更多信息here and here
我正在使用 Visual Studio 2015 Community 并使用 C# 进行编码。
我从串行端口接收到一个字符串。然后我需要从中显示 12 个子字符串,并在 12 个不同的文本框中实时显示它们。
只有在我创建的 Windows 表单中单击加载按钮时才会显示这些值。
直到我使用了一个时间间隔为 2 秒的计时器,我才能够做到。
所以,现在我在文本框中获得了实时值,但是我无法单击表单中的其他按钮。
我对此深陷其中。有什么方法可以在表单中加载实时值,并且仍然可以点击其他按钮吗?
到目前为止,这是我的代码:
using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Diagnostics;
namespace Taskcontinue
{
public partial class Form1 : Form
{// defining a serial port in the code
SerialPort myport = new SerialPort();
int flag = 0;
string input = " "; public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
//detect a * in string and then start extracting the sub-string as defined
private void Skeleton()
{
{
if(myport.IsOpen)
{
myport.Close();
}
myport.BaudRate = 9600;
myport.PortName = "COM9";
myport.Parity = Parity.None;
myport.DataBits = 8;
myport.Open();
{
while (flag == 0)
{
input = "";
char data = Convert.ToChar(myport.ReadChar());
if (data == '*')
{
flag = 1;
input += data;
Debug.WriteLine("star is detected::");
}
}
if (flag == 1)
{
// Debug.WriteLine("WE RE INSIDE FLAG::");
for (int i = 0; i <= 129; i++)
{
// Debug.WriteLine("WE RE IN FOR LOOP::");
input += Convert.ToChar(myport.ReadChar());
}
realvalues();
flag = 0;
}
Debug.WriteLine(input);
}
}
}
//this is the button which on clicking should display the values in text boxes
private void load_values_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void myport_DataReceived(objectsender,SerialDataReceivedEventArgs e)
{
string data = Convert.ToChar(myport.ReadChar()).ToString();
}
//extracting substring from the string from serial port
private void realvalues()
{
tb1.Text = input.Substring(4, 7);
tb2.Text = input.Substring(14, 7);
tb3.Text = input.Substring(24, 7);
tb4.Text = input.Substring(34, 7);
tb5.Text = input.Substring(44, 7);
tb6.Text = input.Substring(54, 7);
tb7.Text = input.Substring(64, 7);
tb8.Text = input.Substring(75, 7);
tb9.Text = input.Substring(86, 7);
tb10.Text = input.Substring(97, 7);
tb11.Text = input.Substring(108, 7);
tb12.Text = input.Substring(123, 7);
}
private void timer1_Tick(object sender, EventArgs e)//timer tick event
{
timer1.Stop();
timer1.Start();
Skeleton();
}
}
}
在你的问题中:“有什么方法可以在表单中加载实时值”,我将按字面意思 real time。
您已经使用了 DataReceived
活动。这个可以用来显示数据。您每 2 秒打开和关闭一次端口。除非有特殊且不可避免的原因,否则您可以在 Form
加载时打开它(或制作一个连接按钮)并保持打开状态。
由于您的数据将在另一个线程中读取,因此您需要使用 BeginInvoke
将其推送到您的盒子中。
public partial class Form1 : Form
{
// You will need these delegate to display your data from the other thread
delegate void del(string data);
del MyDelegate;
SerialPort port;
public Form1()
{
InitializeComponent();
// here you create your delegate that will display your data in the textboxes
MyDelegate = new del(realvalues);
}
private void Form1_Load(object sender, EventArgs e)
{
try
{ // open your port once
port = new SerialPort();
port.PortName = "COM9";
port.BaudRate = 9600;
port.Parity = Parity.None;
port.DataBits = 8;
port.Open();
port.DataReceived += port_DataReceived;
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
private void realvalues()
{
tb1.Text = input.Substring(4, 7);
tb2.Text = input.Substring(14, 7);
tb3.Text = input.Substring(24, 7);
tb4.Text = input.Substring(34, 7);
tb5.Text = input.Substring(44, 7);
tb6.Text = input.Substring(54, 7);
tb7.Text = input.Substring(64, 7);
tb8.Text = input.Substring(75, 7);
tb9.Text = input.Substring(86, 7);
tb10.Text = input.Substring(97, 7);
tb11.Text = input.Substring(108, 7);
tb12.Text = input.Substring(123, 7);
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{ // read the data that has arrived
String s = port.ReadLine();
// call here your Skeleton method and pass the entire data string
string input = Skeleton(s);
// now give the input string to the display method
this.BeginInvoke(MyDelegate, s);
}
private string Skeleton(string portOutput)
{
string input = "";
// parse here through your received string with your algorithm
// and return the constructed input string
return input;
}
}
这应该会实时显示值并让您的 GUI 响应。 如果您仍然真的想要一个额外的 LOAD 按钮 来限制您的实时 写信给我,我编辑我的答案。
有关从其他线程更新 GUI 的更多信息here and here