在运行时刷新控件

时间:2013-12-19 18:16:48

标签: c# runtime refresh

我正在研究WindowsForm并尝试从文件中导入数据,同时我想在读取它时立即在sreen上显示新数据。

我的基本代码如下:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Read_in();
    }

    List<Data> _list = new List<Data>();

    public void Read_in()
    {
        using (StreamReader sr = new StreamReader("in.txt"))
        {
            while (!sr.EndOfStream)
            {
                Data d = new Data
                {
                    a = sr.ReadLine()
                };
                _list.Add(d);
                Controls.Add(d.pb);
            }
        }
    }
}

class Data
{
    public string a;
    public PictureBox pb = new PictureBox()
    {
        BackColor = Color.Red
    };
}

问题是我的数据仅在Read_in()完成时显示。我该怎么帮忙?

这是一篇与此相似的帖子,但我无法理解: Why won't control update/refresh mid-process

2 个答案:

答案 0 :(得分:1)

那是因为正在UI线程中读取数据。您将不得不生成一个新线程并在其中加载数据,从而释放UI线程以进行更新。

正如阿列克谢在这里所说的那样有点解释:

enter image description here

请注意,只要在正常流程中执行UI更新就会阻止UI线程,而在多线程流程中,后台工作人员会完成所有需要处理的更新,即同步。

请修改以下代码并告知我们:

public void Read_in()
{
    BackgroundWorker backgroundWorker1 = new BackgroundWorker();
    backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    backgroundWorker1.RunWorkerAsync();

}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    using (StreamReader sr = new StreamReader("in.txt"))
    {
        while (!sr.EndOfStream)
        {
            Data d = new Data
            {
                a = sr.ReadLine()
            };
            if(this.InvokeRequired)
            {
                 this.Invoke((MethodInvoker)delegate
                 {
                     _list.Add(d);
                     Controls.Add(d.pb);
                 });

            }
            else
            {
                 _list.Add(d);
                 Controls.Add(d.pb);

            }
        }
    }
}

答案 1 :(得分:1)

线程就像超市里的一条线。现在想想你只有一个结账。有你的文件的人正在结帐。那个控制画的家伙就在后面。画家不能支付结账,所以他不能画控件。所以他因为结账时的档案人而被封锁。

你的gui线程是结账线。绘画人员可以通过结账的方式是打开另一个结账。所以他可以付钱并通过结账。之后,他可以绘制控件。所以打开另一个现金就是打开一个新线程。在新线程上,您可以执行文件读取。有了这个,绘画家伙不会通过文件人员在结账时被阻止。

或者你在结帐时设置了两个女人: http://msdn.microsoft.com/de-de/library/system.io.streamreader.readlineasync(v=vs.110).aspx 所以结账不会阻止文件人。