我有一个影院列表,我从应用程序中创建了一个辅助互动程序,可以直接导航到特定的影院。我在查询字符串中传递剧院的id:
我从文件"MainViewModel:cs"中的WCF服务加载影院
在我的主页上,我有一个影院列表,我可以导航到详细信息页面。
但当我想从互动程序中导航时,我出现了一个错误。。。
瓷砖:
ShellTile.Create(new Uri("/TheaterDetails.xaml?selectedItem=" + theater.idTheater, UriKind.Relative), tile, false);
我的影院详情页面:
public partial class TheaterDetails : PhoneApplicationPage
{
theater theater = new theater();
public TheaterDetails()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
if (DataContext == null)
{
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
theater = (from t in App.ViewModel.Theaters
where t.idTheater == index
select t).SingleOrDefault();
DataContext = theater;
....
....
....
错误:
https://dl.dropboxusercontent.com/u/9197067/error.png
就像数据没有加载一样。。。
你知道问题是从哪里来的吗?
解决方案可能很简单,但我是个初学者。。。也许是因为我异步加载数据,而应用程序不会等到它完成。。。
感谢
编辑:
My LoadData()方法:
public void LoadData()
{
client.GetTheatersCompleted += new EventHandler<ServiceReference1.GetTheatersCompletedEventArgs>(client_GetTheatersCompleted);
client.GetTheatersAsync();
// Other get methods...
this.IsDataLoaded = true;
}
private void client_GetTheatersCompleted(object sender, ServiceReference1.GetTheatersCompletedEventArgs e)
{
Theaters = e.Result;
}
您应该检查哪个变量实际上为null。在这种情况下,它看起来是Theaters
(否则错误会更早抛出)。
由于Theaters
是从web调用填充的,因此它很可能是异步调用的,换句话说,当您从LoadData()
返回时,数据还不存在(它仍在等待web调用返回),并且正在等待web服务返回其值。
可能的解决方案:
- 将LoadData()设为
async
函数,然后使用await LoadData()
。这可能需要一些重写/重构以适应async
模式(此处为async
的一般介绍,此处为Windows Phone上的特定web调用) - 一种不涉及黑客攻击(比如循环直到数据出现)的巧妙方法是在数据实际填充时引发一个自定义事件,然后在该事件中进行Tile导航处理。这里有一个基本的例子
因此,感谢Servy在本文中提供的解决方案:使用async/await和void方法
我设法使用async/await来加载数据。
我将LoadData()方法替换为:
public static Task<ObservableCollection<theater>> WhenGetTheaters(ServiceClient client)
{
var tcs = new TaskCompletionSource<ObservableCollection<theater>>();
EventHandler<ServiceReference1.GetTheatersCompletedEventArgs> handler = null;
handler = (obj, args) =>
{
tcs.SetResult(args.Result);
client.GetTheatersCompleted -= handler;
};
client.GetTheatersCompleted += handler;
client.GetTheatersAsync();
return tcs.Task;
}
public async Task LoadData()
{
var theatersTask = WhenGetTheaters(client);
Theaters = await theatersTask;
IsDataLoaded = true;
}
在我的页面中:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
await App.ViewModel.LoadData();
}