文本框填充C#

文本框填充C#,c#,textbox,fill,C#,Textbox,Fill,我的应用程序中有一个文本框,用于显示进程状态。像这样的 for(...) textbox.text = "new line \r\n" + textbox.text 问题是,当它填充时,并没有文本可见,只有白色背景。处理完成后,所有添加的文本都可见。是任何选项,如何解决这个问题(我需要有文本在整个过程中可见) 非常感谢。如果是winforms,请添加Application.DoEvents()在循环中,以便应用程序可以刷新UI 这是最简单但不是最佳的方法 编辑:有人在没有解释的情况下否决了

我的应用程序中有一个文本框,用于显示进程状态。像这样的

for(...)
  textbox.text = "new line \r\n" + textbox.text
问题是,当它填充时,并没有文本可见,只有白色背景。处理完成后,所有添加的文本都可见。是任何选项,如何解决这个问题(我需要有文本在整个过程中可见)


非常感谢。

如果是winforms,请添加
Application.DoEvents()在循环中,以便应用程序可以刷新UI

这是最简单但不是最佳的方法

编辑:有人在没有解释的情况下否决了这个问题。那是公平的。问题发帖人了解backroundworker,希望得到一个更简单的解决方案

无论如何,这个解决方案可能是完美的,这取决于循环的性质。如果它是一个包含大量迭代的循环,每次迭代都需要很短的时间来执行,那么调用Application.DoEvents()将非常有效。我从自己的经验中知道这一点。因为这是一个循环,很可能是这样。或者可以在循环中添加几个DoEvents()。它只是检查windows消息队列并处理挂起的工作

我认为用户不必继续处理应用程序的其他部分

如果它是一个迭代次数很少的循环,并且执行每个循环都需要很长的时间,那么有必要使用线程来完成

但是,请记住,如果新手在使用线程时没有很好地了解其含义(我指的是线程安全),他可能会犯错误。如果应用程序出现死锁怎么办?如何破坏从不同线程使用的非线程安全结构?如果用户在后台线程尚未完成时关闭主窗口,该怎么办?说真的,这个工具在没有经验的人手里可能是炸弹


此外,如果您想使用threading BackgroundWorker,它不是唯一的解决方案。

这是因为只有在方法完成并且消息泵清除后才刷新UI以检查“刷新”消息


可以在循环结束时使用Application.DoEvents()。

使用多线程更新文本框。在您的代码中,更新速度太快,因此您只能看到白色背景。

您的循环正在阻止主UI线程。因此,一旦控件离开循环,UI就会立即更新。我认为你应该在这里使用
BackgroundWorker
。你的问题在这篇文章中讨论得很好。希望它会有所帮助。

您需要使用
BackgroundWorker
从其他线程更新您的gui,并让gui自行工作(就像您可以在gui中执行其他操作一样,如单击复选框或查看其他内容)。然后使用
LogBoxTextAdd
方法从另一个线程更新
TextBox
,这样就不会导致
跨线程
错误

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 += "+";
    }
}
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();
        }
    }
}
使用系统;
使用系统组件模型;
使用System.Windows.Forms;
命名空间Windows窗体应用程序4{
公共部分类Form1:Form{
private readonly BackgroundWorker bg=new BackgroundWorker();
公共表格1(){
初始化组件();
bg.DoWork+=DoWork;
}
私有无效doWork(对象发送方,DoWorkEventArgs e){
对于(int i=0;i<15;i++){
LogBoxTextAdd(“测试”);
}
}
私有void LogBoxTextAdd(字符串varText){
如果(需要调用){
Invoke(newmethodinvoker(()=>LogBoxTextAdd(varText));
}否则{
textBox1.Text=varText+“\r\n”+textBox1.Text;
}
}
私有无效按钮1\u单击(对象发送者,事件参数e){
bg.RunWorkerAsync();
}
}
}

您使用的是哪种UI框架?Windows窗体、WPF、ASP.Net?这是因为您正在阻止for循环(负责绘制和更新窗体)中的主线程。您需要分离一个单独的工作线程来处理数据,并向主窗体发送消息以更新文本框,以便主线程可以自由刷新。问题已解决。我知道BackgroundWorker,但一直在寻找一些更简单的解决方案,如Application.DoEvents()。谢谢大家的快速回答。你知道你基本上是在阻止GUI线程,所以即使GUI更新了,你也不能在GUI上做任何事情,任何需要更长时间才能添加文本的任务都会冻结GUI,用户可能会认为应用程序已经死了。