Windows Phone link from Tile error

2019-09-06 12:32发布

I have a list of theaters and I created a secondary tile from my application to navigate directly to specific theater. I pass the id of the theater in query string :

I load the theaters from a WCF service in the file "MainViewModel.cs"

In my home page, I have a list of theaters and I can navigate to a details page.

But when I want to navigate from the tile, I have an error...

The Tile :

ShellTile.Create(new Uri("/TheaterDetails.xaml?selectedItem=" + theater.idTheater, UriKind.Relative), tile, false);

My TheaterDetails page :

 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;

....
....
....

The error :

https://dl.dropboxusercontent.com/u/9197067/error.png

Like if the data were not loaded...

Do you have an idea where the problem come from ?

The solution could be easy but I am a beginner... Maybe it's because I load the data asynchronously and the application doesn't wait until it's done...

Thanks

EDIT :

My LoadData() method :

 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;
    }

2条回答
成全新的幸福
2楼-- · 2019-09-06 13:04

So the solution that I found, thanks to Servy in this post : Using async/await with void method

I managed to use async/await to load the data.

I replaced my LoadData() method by :

    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;


    }

And in my page :

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        if (!App.ViewModel.IsDataLoaded)
        {
           await App.ViewModel.LoadData();
        }
查看更多
我想做一个坏孩纸
3楼-- · 2019-09-06 13:20

You should check to see which variable is actually null. In this case it looks to be Theaters (otherwise the error would have thrown earlier).

Since Theaters is populated from a web call it is most likely being called asynchronously, in other words when you return from LoadData() the data is not yet there (it's still waiting for the web call to come back), and is waiting for the web service to return its values.

Possible solutions:

  1. Make LoadData() an async function and then use await LoadData(). This might require a bit of rewriting / refactoring to fit into the async pattern (general introduction to async here, and specific to web calls on Windows Phone here)
  2. A neat way of doing this that doesn't involve hacks (like looping until the data is there) is to raise a custom event when the data is actually populated and then do your Tile navigation processing in that event. There's a basic example here.
查看更多
登录 后发表回答