![](/img/trans.png)
[英]How to output data sent through serial port onto a textBox? C# Visual Studio
[英]How to display data received from serial port in a textbox without the text disappearing in Visual Studio C#?
因此,我试图在Visual C#中开发一个简单的应用程序,该应用程序从串行端口获取数据并将其显示在文本框中(以监视温度)。 我正在成功获取和显示数据,使用DataReceived事件更新全局字符串变量,并使用计时器更新文本框上的文本字段,如下所示:
private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
try
{
globalVar.updateTemp = port.ReadLine(); //This is my global string
}
catch (IOException)
{
}
catch (InvalidOperationException)
{
}
catch (TimeoutException)
{
}
}
private void timer1_Tick(object sender, EventArgs e)
{
tempDisplayBox.Text = globalVar.updateTemp; //This is my textbox updating
}
我唯一的问题是,文本框中显示的值一直闪烁,很难读取。 我的计时器设置为每10毫秒触发一次(应该足够快,对吧?)。 有什么方法可以使其更稳定吗? 我意识到这可能是个问题,但老实说,我是个问题:)任何帮助,我们都感激不尽! 谢谢!
您真的需要每10ms
更新一次吗? 每500 ms
或100ms
? 100ms
将需要您的更新方法运行少10倍,因此更新少10倍。 您正在经历的闪烁是由于刷新速度。 您可以创建自定义方法,仅在目标Label
或textBox
值与源port
不同时才更新温度。 但这只会在温度稳定时对闪烁进行分类,当温度开始变化时,它将恢复闪烁。 祝好运 ;-)
UPDATE
嗨,我试图重现条件,但无法使我的文本框或标签闪烁。 我测试它的方法是分配int ntick = 0;
然后增加++ntick;
在timer_tick
方法内部。 结果并没有使任何控件闪烁,并且甚至在每毫秒内更新一次。 我还尝试使用string.Format对方法施加一些负担。 您的应用程序反应灵敏吗?
诀窍是使用双缓冲。 这样,操作系统将在屏幕外重绘该控件,并且仅在完全重绘后才显示该控件。
我遇到了同样的问题,并通过扩展TextBox控件来解决此问题,如下所示:
public FastLogBox()
{
InitializeComponent();
_logBoxText = new StringBuilder(150000);
timer1.Interval = 20;
timer1.Tick += timer1_Tick;
timer1.Start();
SetStyle(ControlStyles.DoubleBuffer, true);
}
void timer1_Tick(object sender, EventArgs e)
{
if (_timeToClear)
{
_logBoxText.Clear();
_timeToClear = false;
}
if (_logQueue.Count <= 0) return;
while (!_logQueue.IsEmpty)
{
string element;
if (!_logQueue.TryDequeue(out element)) continue;
{
_logBoxText.Insert(0, element + "\r\n");
}
}
if (_logBoxText.Length > 150000)
{
_logBoxText.Remove(150000, _logBoxText.Length - 150001);
}
Text = _logBoxText.ToString();
}
public new void Clear()
{
_timeToClear = true;
while (!_logQueue.IsEmpty)
{
string element;
_logQueue.TryDequeue(out element);
}
}
public void AddToQueue(string message)
{
_logQueue.Enqueue(message);
}
}
我还使用计时器和并发队列,以避免使用Invoke从另一个线程更新控件。 在将其放入TextBox之前,我还使用StringBuilder来准备字符串。 构建较大的字符串时,StringBuilder速度更快。
您可以使用ReadExisting()
读取全部数据。 您需要处理SerialPort
DataReceived
事件
serialPort1.ReadExisting();
样品:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
String myData=serialPort1.ReadExisting();
}
示例代码:在这里,我想向您展示读取数据的代码(RFID标签代码,长度基本上为12)
String macid = "";
private void DoWork()
{
Invoke(
new SetTextDeleg(machineExe ),
new object[] { macid });
macid = "";
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string str1;
macid += serialPort1.ReadExisting();
if (macid.Length == 12)
{
macid = macid.Substring(0, 10);
Thread t = new Thread(new ThreadStart(DoWork));
t.Start();
}
}
public void machineExe(string text)
{
TextBox1.Text=text;
}
非常感谢您的回答! 我找到了解决此问题的方法:而不是通过重写TextBox.Text属性来替换文本框的内容-正如HenningNT所暗示的那样,它刷新控件并导致闪烁-我现在使用的是TextBox.AppendText方法。 但是,由于一次只显示一行数据,因此在多行模式下使用文本框,并在附加文本之前使用Environment.NewLine跳转到新行。 至于更新方法,我已经回到使用计时器的原因,因为由于某种原因,当我关闭表单时,invoke方法使应用程序崩溃。 另外,虽然我猜我做错了,但是启用双重缓冲并没有多大帮助。它仍然会闪烁一点,但是现在好多了:)我知道这并不是一个完美的解决方案(更多内容解决方法),因此我将继续寻找它。 如果找到它,我将确保在这里进行更新;)我的代码:
private void timer1_Tick(object sender, EventArgs e) //Timer to update textbox
{
if (tempDisplayBox.Text != globalVar.updateTemp) //Only update if temperature is different
{
try
{
tempDisplayBox.AppendText(Environment.NewLine);
tempDisplayBox.AppendText(globalVar.updateTemp);
}
catch (NullReferenceException)
{
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.