UI元素未更新

时间:2013-10-13 12:48:51

标签: c# wpf uielement

如果您可以将其描绘为加载栏:

for (int i = 0; i < r.Width / 2; i++) //Fills half the loading bar.
{         
    Rectangle rect = can.Children[3] as Rectangle; //getting the 3rd element of my Canvas
    if (rect != null)
     {
         rect.Fill = brush;
         rect.Width = i;
         Thread.Sleep(50);
     }
}

因此,应用程序不会显示添加其他矩形的进度。相反,它只是冻结线程休眠的总时间,当for循环结束时,它将显示整个条形。

为什么会这样?

我知道内置了一个加载栏,但这只是我遇到的问题的一个例子。

1 个答案:

答案 0 :(得分:2)

我建议你开始阅读有关线程,后台工作人员,调度员的信息。除非您向解决方案添加线程,否则整个应用程序将在UI线程的帮助下运行。

如果您有可以连续执行的任务,则无需实现Threads或后台工作程序。在你的情况下,你正在尝试做2个任务。

  1. 更新矩形并在窗口上绘制
  2. 睡眠线程50毫秒
  3. 当UI线程执行thread.Sleep(50);它无法绘制(在矩形中显示进度)。这就是你的应用程序冻结几秒钟并在你看到任何进展之前完成的原因。我将尝试用2个例子来解释这个。

    示例1 IsIndeterminate="True"Button1的进度条添加到演示应用程序中。

    <ProgressBar IsIndeterminate="True"  Height="20" Name="progressBar1" Width="177" Visibility="Hidden" />
    

    在代码背后,

     private void button1_Click(object sender, RoutedEventArgs e)
            {
                progressBar1.Visibility = Visibility.Visible;
                Thread.Sleep(5000);
                progressBar1.Visibility = Visibility.Hidden;
            }
    

    如果您运行此代码,则代码将以串行方式执行时,您将看不到任何进度条。要确保正确显示进度条并正确隐藏,请执行以下更改。

    示例2:

    private void button1_Click(object sender, RoutedEventArgs e)
            {
                progressBar1.Visibility = Visibility.Visible;
                Thread t = new Thread(DoMyWork);
                t.Start();
            }
    
       private void DoMyWork()
                    {
                        Thread.Sleep(5000);
                        //hide the progress bar after completing your work
                        this.Dispatcher.Invoke((Action)delegate { progressBar1.Visibility = Visibility.Hidden; });
                    }
    

    enter image description here

    运行此代码,您可以看到当UI线程更新进度条时,创建的新线程执行DoMyWork函数。

    您需要this.Dispatcher.Invoke((Action)delegate,因为在UI线程中创建了progressBar1,您无法在另一个线程中访问它。 ieThread t = new Thread(..)

    P.S.-这对于编码很脏。只是想知道OP的情况应该如何运作。