使用MVVM处理HTTP GET请求

时间:2014-01-31 02:57:03

标签: c# mvvm windows-phone-8 http-get

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

提前致谢!

在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
        {

        }
    }

}

1 个答案:

答案 0 :(得分: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));
    }
}