如何在Loaded处理程序中更新控件?

时间:2014-11-18 11:12:00

标签: c# wpf events

通常的例程,进度条,用户单击按钮,进程运行,进度条更新。经典。

但是我想在整个应用程序启动的那一刻运行该过程,所以我在Loaded Window处理程序中运行它(我应用程序中唯一的窗口)。

现在,进度条未更新。如何克服这个问题?

用于更新进度条的测试器。

for (int i = 0; i <= 100; i++)
{
    Thread.Sleep(100);

    Progress.Dispatcher.Invoke(
    System.Windows.Threading.DispatcherPriority.Render, new Action(delegate() { ++Progress.Value; }));
}

1 个答案:

答案 0 :(得分:1)

因为您将所有工作都放在用于更新Progressbar的UI线程上,所以Progressbar在工作完成之前不会更新。将工作放在后台线程上,并使用Progressbar从后台线程更新Dispatcher.BeginInvoke

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        for (int i = 0; i <= 100; i++)
        {
            Thread.Sleep(100);                    
            Progress.Dispatcher.BeginInvoke(new Action(delegate() { ++Progress.Value; }), null);
        }
    });
}

如果您使用的是.NET 2.0(不使用TPL),则可以使用ThreadPool

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    ThreadPool.QueueUserWorkItem( (o) =>
    {
        for (int i = 0; i <= 100; i++)
        {
            Thread.Sleep(100);
            Progress.Dispatcher.BeginInvoke(new Action(delegate() { ++Progress.Value; }), null);
        }
    });
}

或者使用await-async(.NET 4.5),请参阅,您可以从标记为DoWork()的任何方法中调用async

async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    await DoWork();
}

async Task DoWork()
{
    await Task.Run(async () =>
    {
        for (int i = 0; i <= 100; i++)
        {
            Thread.Sleep(100);
            await Progress.Dispatcher.BeginInvoke(new Action(delegate() { ++Progress.Value; }), null);
        }
    });
}