Проблема вызова ASync JSON REST с MVVM - PullRequest
0 голосов
/ 10 декабря 2010

Я пытаюсь реализовать паттерн MVVM для моего приложения WP7 Silverlight и столкнулся с проблемой асинхронного вызова JSON Rest. Я перешел в свой класс ViewModel следующими двумя методами, которые были на моей странице приложения WP7.

public void FetchGames()
{            

    ObservableCollection<Game> G = new ObservableCollection<Game>();
    //REST call in here
    var webClient = new WebClient();
    Uri uri = new Uri("http://www.somewebsite.com/get/games/league/" + league);
    webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(OpenReadCompletedGames);   
    webClient.OpenReadAsync(uri);
}

private void OpenReadCompletedGames(object sender, OpenReadCompletedEventArgs e)
{
    DataContractJsonSerializer ser = null;
    ser = new DataContractJsonSerializer(typeof(ObservableCollection<Game>));
    Games = ser.ReadObject(e.Result) as ObservableCollection<Game>;
    this.IsDataLoaded = true;

}

Теперь проблема в том, что, поскольку это асинхронный вызов, следующий код не работает. Следующий код находится на странице моего приложения.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if (NavigationContext.QueryString.TryGetValue("league", out league))
    {              

 try
 {
     App.gViewModel.league = league;
     App.gViewModel.FetchGames();
     if(App.gViewModel.IsDataLoaded)
     {
  lbTeams.ItemsSource = App.gViewModel.Games;
     }     
 }
 catch ()
 {                
     //error logging in here              
 }
    }

}

Выполнение кода показывает, что FetchGames вызывается, затем переходит на следующую строку (если (App.gViewModel.IsDataLoaded) ) до завершения асинхронного вызова. Поэтому IsDataLoaded всегда ложно, и я не могу привязать список на странице.

Много гугля, у меня есть несколько возможных решений, но я не могу преобразовать их в свою конкретную проблему. Один такой, и это связано со стилем продолжения прохождения ». Я не мог заставить его работать, но был бы очень признателен за помощь.

Спасибо!

void DoSomethingAsync( Action<string> callback ) { 
    HttpWebRequest req; // TODO: build your request 

    req.BeginGetResponse( result => { 
        // This anonymous function is a closure and has access  
        // to the containing (or enclosing) function. 
        var response = req.EndGetResponse( result ); 

        // Get the result string and call the callback 
        string resultString = null; // TODO: read from the stream 

        callback(resultString); 
    }, null ); 
} 

1 Ответ

3 голосов
/ 10 декабря 2010

Это можно решить, переместив

lbTeams.ItemsSource = App.gViewModel.Games;

до конца метода OpenReadCompletedGames. Вам нужно будет использовать Диспетчер для обновления пользовательского интерфейса отсюда.

Dispatcher.BeginInvoke( () => { lbTeams.ItemsSource = App.gViewModel.Games; } );
...