我目前正在开发一款需要使用网络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
{
}
}
}
答案 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));
}
}