,

Walking Through the Bookshop Sample Application

This chapter’s sample app provides the beginnings of a simple data driven e-commerce app that demonstrates the use of navigation, transient and persistent state, image caching, and WCF services. It allows the user to select from a list of books, retrieved from a WCF service, and to view each item’s details on a separate details page.

The ProductsViewModel class retrieves a list of Product objects from a WCF service. Each product has various properties such as a description, price, and an image URI.

The ProductsViewModel saves and restores its own transient state consisting of the list of products it retrieves from the WCF service (see Listing 3.8).

The code for this section resides in the Navigation directory of the WPUnleashed. Examples project in the downloadable sample code.

The viewmodel’s constructor determines whether transient state exists for itself. If so, it restores the list of Products or else it requests the list of products from the WCF using the BookshopServiceClient. The call occurs asynchronously, and the products list is populated after the call completes.

The ViewModelBase class subclasses the NotifyPropertyChangeBase class, which implements INotifyPropertyChanged. The source for NotifyPropertyChangeBase is located in the downloadable sample code, and was discussed in Chapter 2, “Fundamental Concepts in Windows Phone Development.”

LISTING 3.8. ProductsViewModel Class (excerpt)


public class ProductsViewModel : ViewModelBase
{
    readonly IDictionary<string, object> transientStateDictionary;
    const string transientStateKey = "ProductsViewModel_Products";

    public ProductsViewModel(
        IDictionary<string, object> transientStateDictionary)
    {
        this.transientStateDictionary = ArgumentValidator.AssertNotNull(
                transientStateDictionary, "transientStateDictionary");

        LoadTransientState();
        if (products != null)
        {
            return;
        }

        BookshopServiceClient client = new BookshopServiceClient();
        client.GetProductsCompleted += (sender, args) =>
        {
            if (args.Error != null)
            {
                MessageService.ShowError("Unable to retrieve products.");
                return;
            }

            Products = args.Result;
            Loaded = true;
        };
        client.GetProductsAsync();
    }

    ObservableCollection<Product> products;

    public ObservableCollection<Product> Products
    {
        get
        {
            return products;
        }
        private set
        {
            Assign(ref products, value);
        }
    }
    bool loaded;

    public bool Loaded
    {
        get
        {
            return loaded;
        }
        private set
        {
            Assign(ref loaded, value);
        }
    }

    public void SaveTransientState()
    {
        transientStateDictionary[transientStateKey] = products;
    }

    public void LoadTransientState()
    {
        object transientState;
        if (transientStateDictionary.TryGetValue(
                transientStateKey, out transientState))
        {
            products = transientState as ObservableCollection<Product>;
            if (products != null)
            {
                Loaded = true;
            }
        }
    }
}


Within the OnNavigatingTo method of the ProductsView page, a ProductsViewModel is instantiated and assigned to the page’s DataContext. The ProductsViewModel is passed the transient state dictionary for the page (see Listing 3.9).

The OnNavigatingTo and OnNavigatedFrom methods are used to inform the viewmodel when to save its state.

LISTING 3.9. ProductsView Class


public partial class ProductsView : PhoneApplicationPage
{
    public ProductsView()
    {
        InitializeComponent();
    }

    ProductsViewModel ViewModel
    {
        get
        {
            return (ProductsViewModel)DataContext;
        }
    }

    bool loaded;

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        Debug.WriteLine("ProductsView OnNavigatedTo");
        base.OnNavigatedTo(e);

        if (!loaded)
        {
            DataContext = new ProductsViewModel(State);
            loaded = true;
        }

        ViewModel.LoadTransientState();
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);
        Debug.WriteLine("ProductsView OnNavigatedFrom");
        ViewModel.SaveTransientState();
    }
}


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.184.126