简体   繁体   中英

How to update TextBlock when async HttpRequest is finished?

I'm working on an app and I'm restructuring my code.

On my MainPage.xaml.cs I have a TextBlock and a ListBox. I have separate file (Info.cs) that handles the HttpRequest to get the information that I need to load.

The HttpRequest in Info.cs gets information from a weather API. When it gets all the information it puts the info in a ObservableCollection.. This ObservableCollection is bind to the ListBox.

Now, I'd like to update the TextBlock when the HttpRequest is finished, to show the user that all the information has been loaded.

How can I achieve this?

MainPage.xaml.cs:

        WeatherInfo weatherInfo = new WeatherInfo();
        weatherInfo.getTheWeatherData();

        DataContext = weatherInfo;
        WeatherListBox.ItemsSource = weatherInfo.ForecastList;

        StatusTextBlock.Text = "Done.";

In the Info.cs I have a Dispatcher to fill the ForecastList:

    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        ForecastList.Clear();
        ForecastList = outputList;    
    }

What happens now is that the TextBlock instantly changes to "Done!" (doh, its Async!) but how can I change this? So it 'waits' on the ListBox to be updated? Unfortunatly there is no 'ItemsSourceChanged' event in Windows Phone.

I suggest to use the new async + await power from C# 5.0, This is actually a good practice to use async programming in WP8.

assuming you have control of getTheWeatherData() method, and that you can mark it as async method that returns Task , you will be able to call it using await modifier.

await will not block the UI, and will cause the next code lines to be executed only after the task is done.

    WeatherInfo weatherInfo = new WeatherInfo();
    await weatherInfo.getTheWeatherData();

    DataContext = weatherInfo;
    WeatherListBox.ItemsSource = weatherInfo.ForecastList;

    StatusTextBlock.Text = "Done.";

Edit: It is supported on WP 8 , and on WP 7.5 through Microsoft.Bcl.Async Nuget Package

If async programming is not an option, you can always create a callback event in WeatherInfo class that will be signaled inside getTheWeatherData() , and register to it on the UI.

One option looks as follows:

public static void DoWork(Action processAction)
{
  // do work
  if (processAction != null)
    processAction();
}

public static void Main()
{
  // using anonymous delegate
  DoWork(delegate() { Console.WriteLine("Completed"); });

  // using Lambda
  DoWork(() => Console.WriteLine("Completed"));
}

Both DoWork() calls will end with calling the callback that is passed as a parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM