2014-01-31 60 views
2

我目前正在开发需要使用Web API的Windows Phone 8应用程序。当我决定转向MVVM模型时,我将必要的代码从Web API下载到单独的类中。在实现了所有必要的功能后,我意识到线程不会等待数据完成下载(或者至少不会等待必要的代码运行),线程将通过ViewModel构造函数并返回空白列表绑定到我的LongListSelector控件。当调试时我意识到线程实际上会在我的ViewModel内通过DownloadCompleted方法,但总是在我的LongListSelector的ItemsSource已经设置为空白列表之后。最后,我确实得到了一个正确填充的数据列表,只不过LongListSelector已经被绑定到了空List。无论如何,我可以改变我在做什么,这样我的LongListSelector实际上绑定到我从Web获得的真实数据,而不是在它正确地填充数据之前绑定到空List。无论是在某种程度上等待所有必要的代码在线程移动之前运行,还是在我的List被数据正确填充时更新View,我都愿意接受任何类型的建议,只要他们让我的代码最终工作。使用MVVM的HTTP GET请求

在此先感谢!

在MainPage.xaml.cs中:

public void Retrieve() 
    { 
     MySets.ItemsSource = new MySetsViewModel(CurrentLogin).BindingList;   
    } 

MySetsView模型定义如下:

public class MySetsViewModel 
{ 
    User CurrentLogin; 
    List<Sets> SetsList; 
    public List<Sets> BindingList { get; set; } 

    public MySetsViewModel(User CurrentLogin) 
    { 
     this.CurrentLogin = CurrentLogin; 
     Retrieve(CurrentLogin); 
    } 

    public async void Retrieve(User CurrentLogin) 
    { 
     if (IsolatedStorageSettings.ApplicationSettings.Contains("AccessToken")) 
     { 
      CurrentLogin.AccessToken = IsolatedStorageSettings.ApplicationSettings["AccessToken"].ToString(); 
     } 
     if (IsolatedStorageSettings.ApplicationSettings.Contains("UserID")) 
     { 
      CurrentLogin.UserId = IsolatedStorageSettings.ApplicationSettings["UserID"].ToString(); 
     } 

     try 
     { 
      HttpClient client = new HttpClient(); 
      HttpRequestMessage request = new HttpRequestMessage(); 
      client.DefaultRequestHeaders.Add("Authorization", "Bearer " + CurrentLogin.AccessToken); 
      client.DefaultRequestHeaders.Add("Host", "api.quizlet.com"); 
      var result = await client.GetAsync(new Uri("https://api.quizlet.com/2.0/users/" + CurrentLogin.UserId + "/sets"), HttpCompletionOption.ResponseContentRead); 
      string jsonstring = await result.Content.ReadAsStringAsync(); 
      DownloadCompleted(jsonstring); 
     } 
     catch 
     { 

     } 


    } 

    void DownloadCompleted(string response) 
    { 
     try 
     { 
      //Deserialize JSON into a List called Sets 
      this.BindingList = Sets; 

     } 
     catch 
     { 

     } 
    } 

} 

回答

2

所有你需要做的是落实在你的视图模型INotifyPropertyChanged。在setter中为“BindingList”提升PropertyChanged事件,视图将自行更新。

public class MySetsViewModel : INotifyPropertyChanged 
{ 
    public List<Sets> BindingList 
    { 
     get { return _bindingList; } 
     set 
     { 
      _bindingList = value; 
      RaisePropertyChanged("BindingList"); 
     } 
    } 
    private List<Sets> _bindingList; 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected virtual void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
}