![](/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.