用C#填充的TextBox
本文关键字:TextBox 填充 | 更新日期: 2023-09-27 18:28:51
我的应用程序中有一个TextBox,用于显示进程状态。像这样的
for(...)
textbox.text = "new line 'r'n" + textbox.text
问题是,当填充时,没有文本可见,只有白色背景。流程完成后,所有添加的文本都可见。是任何选项,如何解决这个问题(我需要在整个过程中看到文本)。
非常感谢。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerAsync();
}
delegate void Temp();
void bg_DoWork(object sender, DoWorkEventArgs e)
{
Temp temp = new Temp(UpdateTextBox);
while (true)
{
Thread.Sleep(1000);
textBox1.BeginInvoke(temp);
}
}
void UpdateTextBox()
{
textBox1.Text += "+";
}
}
如果是winforms,请在循环中添加Application.DoEvents();
,以便应用程序可以刷新UI。
这是最简单但不是最佳的方法
编辑:有人在没有解释的情况下否决了这个问题。这是公平的。问题发布者了解幕后工作者,想要一个更简单的解决方案。
无论如何,这个解决方案可以是完美的,这取决于循环的性质。如果它是一个有很多迭代的循环,每个迭代都需要很短的时间来执行,那么调用Application.DoEvents()将非常有效。我从自己的经历中知道这一点。因为这是一个循环,所以很有可能是这样。或者可以在循环中添加几个DoEvents()。它只是检查windows消息队列并处理挂起的工作。
我不认为用户必须继续处理应用程序的其他部分。
如果它是一个迭代次数很少的循环,并且每次执行都需要很长时间,那么就必须使用线程来完成。
但是,请记住,如果一个新手在不太清楚其含义的情况下使用线程,他可能会犯错误(我指的是线程安全)。如果应用程序出现死锁怎么办?损坏不同线程使用的非线程安全结构会怎样?如果用户在后台线程还没有完成的情况下关闭了主窗口,该怎么办?说真的,这个工具在没有经验的人手里可能是一颗炸弹。
此外,如果你想使用线程BackgroundWorker并不是唯一的解决方案。
这是因为只有在方法完成并且清除消息泵以检查"刷新"消息之后,UI才会刷新。
您可以在循环结束时使用Application.DoEvents()。
使用多线程更新文本框。在您的代码中,更新发生得太快,所以您只能看到白色背景。
您的循环正在阻塞主UI线程。因此,一旦控件离开循环,UI就会立即更新。我认为你应该在这里使用BackgroundWorker
。你的问题在这篇文章中讨论得很好。希望这会有所帮助。
您需要使用BackgroundWorker
从其他线程更新gui,并让gui自己工作(就像在中一样,您可以在gui中执行其他操作,如单击复选框或查看其他内容)。然后使用LogBoxTextAdd
方法从另一个线程更新TextBox
,这样就不会导致Cross-Thread
错误。
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApplication4 {
public partial class Form1 : Form {
private readonly BackgroundWorker bg = new BackgroundWorker();
public Form1() {
InitializeComponent();
bg.DoWork += doWork;
}
private void doWork(object sender, DoWorkEventArgs e) {
for (int i = 0; i < 15; i++) {
LogBoxTextAdd("TEST");
}
}
private void LogBoxTextAdd(string varText) {
if (InvokeRequired) {
textBox1.Invoke(new MethodInvoker(() => LogBoxTextAdd(varText)));
} else {
textBox1.Text = varText + "'r'n" + textBox1.Text;
}
}
private void button1_Click(object sender, EventArgs e) {
bg.RunWorkerAsync();
}
}
}