2010-12-09 3 views
0

J'essaie d'implémenter le pattern MVVM pour mon application WP7 Silverlight et je rencontre un problème avec l'appel asynchrone JSON Rest. J'ai déplacé dans ma classe ViewModel les deux méthodes suivantes qui étaient sur ma page d'application WP7.Problème d'appel ASNEM JSON REST avec MVVM

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; 

} 

Maintenant le problème est que parce que c'est un appel asynchrone le code suivant ne fonctionne pas. Le code suivant est sur ma page d'application.

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    
} 
    } 

} 

pas à pas à travers le code montre que FetchGames est appelé frappe alors la ligne suivante (si (App.gViewModel.IsDataLoaded) ) avant que l'appel async est terminé. Donc IsDataLoaded est toujours faux et je ne peux pas lier la listbox sur la page. Faire beaucoup de googleing J'ai quelques solutions possibles, mais je suis incapable de les convertir à mon problème particulier. On est comme ça et ça a à voir avec le style de passage continu. Je ne pouvais pas le faire fonctionner et j'apprécierais grandement de l'aide.

Merci!

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); 
} 

Répondre

3

Cela peut être résolu en déplaçant

lbTeams.ItemsSource = App.gViewModel.Games; 

à la fin de la méthode OpenReadCompletedGames. Vous devrez utiliser Dispatcher pour mettre à jour l'interface utilisateur à partir d'ici.

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

@Mick vous me battre cette fois; o) –

+0

@Mick Merci pour la réponse. Lorsque je mets votre code dans la méthode OpenReadCompletedGames, j'obtiens cette erreur: Erreur Impossible de convertir l'expression lambda en type 'System.Delegate' car ce n'est pas un type de délégué – sleeprince

+0

ajouter un cast à l'action devrait fonctionner: Dispatcher.BeginInvoke (** (Action) (**() => {lbTeams.ItemsSource = App.gViewModel.Games;} **) **); –