Exercise 4: Creating the Windows Phone 7 Application

In this exercise, you will create a Windows Phone 7 application to read from the list created in Exercise 1. The application will allow users to opt in for notifications. The application will enable and disable toast notifications based on the setting.

Task 1 – Adding the WP7.Notification.Events.PhoneApp Project to the Solution

In this task, you add the existing WP7.Notification.Events.PhoneApp project to the solution.

  1. In the Solution Explorer, right-click the WP7.Notification.Events solution, and select Add | Existing Project.
  2. Browse to WP7.Notification.Events.PhoneApp.csproj located in the PhoneApp folder.
  3. Click Open.

    Figure 10

    Solution Explorer with three projects displayed

Task 2 – Configuring Constants in the Windows Phone 7 Application

In this task, you will configure the constants used in the Windows Phone 7 application to work with your development environment.

  1. In the WP7.Notification.Events.PhoneApp project, in the Utilities folder, open the Constants.cs file.
  2. Change the value for the USER_NAME and USER_PASSWORD constants to represent a Forms Based Authentication user specific to your development environment. For this lab, the user requires read and write permissions.
  3. Change the value for the AUTHENTICATION_SERVICE_URL constant to the URL specific to your development environment.
  4. The following code example demonstrates the value for a SharePoint server named fbawp7.

    C#

    public const string AUTHENTICATION_SERVICE_URL = "https://fbawp7/_vti_bin/authentication.asmx";

  5. Change the LIST_TITLE constant to Maintenance Training Schedule.
  6. Change the LIST_ID constant to the list id of the Maintenance Training Schedule.
    1. Open the Maintenance Training Schedule list in Internet Explorer.
    2. Select the Calendar Ribbon tab.
    3. Click List Settings Ribbon button.
    4. Select the value of the List URL parameter from the browser’s address bar.
    5. The value of the list id in the address bar is URL encoded. Remove the %7B and %7D values at the beginning and end of the parameter. Replace %2D with the dash character.

      For example:

      %7B618FD6BA%2DE587%2D4C93%2D9143%2DD21B2C01E8AD%7D

      Is converted to:

      618FD6BA-E587-4C93-9143-D21B2C01E8AD

    6. Copy the unencoded list id to the LIST_ID constant value.

      C#

      public const string LIST_ID = "618FD6BA-E587-4C93-9143-D21B2C01E8AD";

      Note:
      Note: If the list id constant is not correct, the event handler will not receive the channel Uri (device) from the registration service.

      Note:
      Note: The above code is an example. You must use your unique list id.

Task 3 – Completing the SettingsViewModel.cs Class

In this task, you will complete the existing SettingsViewModel class. This class manages the application’s connection and bindings for notification.

  1. In the Solution Explorer, open the SettingsViewModel.cs file located in the ViewModels folder.
  2. Add the following code under the //TODO: 7.1.4 comment to define the Current property:

    C#

    private static SettingsViewModel current; public static SettingsViewModel Current { get { return current; } }

  3. The above code creates a singleton-type property. This allows the code to have only one instance of this class at a time. This view model class contains the code to manage notifications. Creating a singleton of this class allows the code to be available at all times.
  4. Add the following code under the //TODO: 7.1.5 comment to define the IsNotificationEnabled property.

    C#

    public bool IsNotificationEnabled { get { if (settings.Contains(Constants.IS_NOTIFICATION_ENABLED)) { return (bool)settings[Constants.IS_NOTIFICATION_ENABLED]; } else { settings.Add(Constants.IS_NOTIFICATION_ENABLED, false); return false; } } set { if (settings.Contains(Constants.IS_NOTIFICATION_ENABLED)) { settings[Constants.IS_NOTIFICATION_ENABLED] = value; } else { settings.Add(Constants.IS_NOTIFICATION_ENABLED, value); } if (value == true) { EnableNotifications(); } else { DisableNotifications(); } UpdateNotificationBindings(); RaisePropertyChanged("IsNotificationEnabled", this, PropertyChanged); } }

  5. The IsNotificationEnabled property is persisted in isolated storage. This value is bound to the Settings.xaml view. When the user enables or disables notifications in the user interface or when the application starts the IsNotification value is set and the code will set the correct bindings. When the end user opts to enable notifications, the property configures the notifications on the phone..
  6. Add the following code under the //TODO: 7.1.6 comment to define the SettingsViewModel contstructor.

    C#

    public SettingsViewModel() { if (current != null) { throw new InvalidOperationException("Only 1 SettingsViewModel Allowed"); } settings = IsolatedStorageSettings.ApplicationSettings; current = this; }

  7. The above code creates the view model and sets the current variable to the newly created object. This creates our singleton object.
  8. Add the following code under the //TODO: 7.1.7 comment to define the EnableNotifications method.

    C#

    public void EnableNotifications() { Channel = HttpNotificationChannel.Find(Constants.CHANNEL_NAME); if (Channel == null) { Channel = new HttpNotificationChannel(Constants.CHANNEL_NAME); Channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(Channel_ChannelUriUpdated); Channel.Open(); } else { Channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(Channel_ChannelUriUpdated); ChannelUri = Channel.ChannelUri; UpdateNotificationBindings(); } }

  9. The above code will attempt to find an existing HTTPNotificationChannel. The HTTPNotificationChannel object contains information about the persistant channel between the application, the phone OS and the Microsoft Push Notification service. Channels are defined using a channel name. The application will create a new channel if an existing channel is not found. Once there is a channel available, the code will update the notification bindings by calling UpdateNotificationBindings.
  10. Add the following code under the //TODO: 7.1.8 comment to define the RegisterWithNotificationSource method.

    C#

    internal void RegisterWithNotificationSource(Uri channelUri) { var svc = new NotificationRegistration.ListNotificationChannelsClient(); svc.RegisterAsync(channelUri.ToString(), Constants.LIST_ID); }

  11. The above code will use the service proxy created by Visual Studio to register the device’s channel URI with the NotificationRegistration WCF service after the application has a channel. The registration service tracks which notification channels (device) are listening to notifications. In this application, the registration service tracks the channel Uri and an associated list id.
  12. Add the following code under the //TODO: 7.1.9 comment to define the UpdateNotificationBindings method.

    C#

    private void UpdateNotificationBindings() { if (IsNotificationEnabled) { if (Channel != null && !Channel.IsShellToastBound) { Channel.BindToShellToast(); } } else { if (Channel.IsShellToastBound) { Channel.UnbindToShellToast(); } } }

  13. The above code will bind or unbind the device to the toast notifications. When bound, this code alerts the phone that it is listening for toast notifications. When not bound to the toast notifications the phone will not display a toast notification sent from the Push Notification Service. Developers do not have access to modify the toast displayed by the phone. When bound to the toast notification the user interface will display a toast with the text sent in the Xml payload.
  14. Save and close SettingsViewModel.cs file.

Task 4 – Completing the MainPage.xaml.cs File

In this task, you will complete the MainPage.xaml.cs file.

  1. In the Solution Explorer, in the WP7.Notification.Events.PhoneApp project, right click MainPage.xaml and select View Code.
  2. Add the following code under the //TODO: 7.1.10 comment to define the MainPage constructor method.

    C#

    public MainPage() { InitializeComponent(); viewModel = new MainViewModel(); DataContext = viewModel; viewModel.GetEvents(); App.settingsViewModel = new SettingsViewModel(); var settings = SettingsViewModel.Current; if (settings.IsNotificationEnabled) { settings.EnableNotifications(); } }

  3. The above constructor code sets the viewModel and DataContext for the main page. The code creates the single SettingsViewModel object and determines if notifications are enabled. If notifications are enabled it calls the EnableNotifications method of the SettingsViewModel to create and configure the notification channel. This sets the state of the application whenever it is executed
  4. Save and close MainPage.Xaml.cs.

Task 5 – Adding a Reference to the SharePoint Lists.asmx Web Service

In this task, you will add a reference to the SharePoint lists.asmx Web service. Lists.asmx is used to query the list and display items in the application.

  1. In the Solution Explorer, in the WP7.Notification.Events.PhoneApp project, right click Service References and select Add Service Reference.
  2. In the Addresstextbox enter the URL to the lists.asmx SharePoint web service for the site where you created the Maintenance Training Schedule list.
  3. Example: https://fbawp7/_vti_bin/lists.asmx
  4. Click Go.
  5. Once the service is resolved, enter ListSvc in the Namespace textbox.
  6. Click OK.

Task 6 – Adding a Reference to the NotificationRegistration WCF Service

In this task, you will add a reference to the NotificationRegistration WCF service. The WCF service is used to register the device’s channel Uri (from Push Notification Service) and list id. The WCF service is a custom WCF service that we use to determine who should be notified of events for each list.

  1. In the Solution Explorer, in the WP7.Notification.Events.PhoneApp project, right click Service References and select Add Service Reference.
  2. Click Discover.
  3. After the ListNotificationChannelsSvc service is discovered, enter NotificationRegistration in the Namespace textbox.
  4. Click OK.

In this task, you will modify the ServiceReferences.ClientConfig file to support the CookieContainer used with Forms BasedAuthentication. The code used to authenticate to the SharePoint server in this lab uses Forms Based Authentication. Forms Based Authentication requires the use of a CookieContainer. Please see the Security With SharePoint And Windows Phone 7 Applications Module for more information about Forms Based Authentication.

  1. In the WP7.Notification.Events.PhoneApp project, open the ServiceReferences.ClientConfig file.
  2. Locate the ListsSoap binding element.
  3. Add the following attribute to the ListsSoap binding element.

    XML

    enableHttpCookieContainer="true"

  4. The following screenshot shows what the ListSoap binding element looks like after the above code is added.

    Figure 11

    Adding the enableHttpCookieContainer in the ServiceReferences.ClientConfig file

    Note:
    The following exception will occur if you do not make this change to the ServiceReferences.ClientConfig file.

    Figure 12

    Error message received when editing a service with the enableHttpCookieContainer attribute

    Note:
    If you change the interface to one or both of the services the application calls and need to update the service reference you will need to remove the XML code above from the ServiceReferences.ClientConfig file then update the service reference. After the service reference update is complete, add the XML code back to the ServiceReferences.ClientConfig file.