我正在尝试为我的WP7 Silverlight应用程序实现MVVM模式,我遇到了异步JSON Rest调用的问题。我将我的WP7应用页面中的以下两种方法移入了我的ViewModel类。
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然后命中下一行(if(App.gViewModel.IsDataLoaded) )在异步调用完成之前。所以IsDataLoaded总是假的,我不能绑定页面上的列表框。
做了很多googleing我有一些可能的解决方案,但我无法将它们转换为我的特定问题。一个是这样的,它与延续传递风格有关。我无法让它工作,并非常感谢一些帮助。
谢谢!
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 );
}
答案 0 :(得分:3)
这可以通过移动来解决
lbTeams.ItemsSource = App.gViewModel.Games;
到OpenReadCompletedGames方法的末尾。您需要使用Dispatcher从此处更新UI。
Dispatcher.BeginInvoke( () => { lbTeams.ItemsSource = App.gViewModel.Games; } );