## Xamarin Dev Days Hands On Lab Today, we will be building a cloud connected [Xamarin.Forms](http://xamarin.com/forms) application that will display a list of speakers at Xamarin Dev Days and show their details. We will start by building some business logic backend that pulls down json from a RESTful endpoint and then we will connect it to an Azure Mobile App backend in just a few lines of code. ### Get Started Open **Start/DevDaysSpeakers.sln** This solution contains 4 projects * DevDaysSpeakers (Portable) - Portable Class Library that will have all shared code (model, views, and view models). * DevDaysSpeakers.Droid - Xamarin.Android application * DevDaysSpeakers.iOS - Xamarin.iOS application * DevDaysSpeakers.UWP - Windows 10 UWP application (can only be run from VS 2015 on Windows 10) ![Solution](http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/44f4caa9-efb9-4405-95d4-7341608e1c0a/Portable.png) The **DevDaysSpeakers (Portable)** also has blank code files and XAML pages that we will use during the Hands on Lab. #### NuGet Restore All projects have the required NuGet packages already installed, so there will be no need to install additional packages during the Hands on Lab. The first thing that we must do is restore all of the NuGet packages from the internet. This can be done by **Right-clicking** on the **Solution** and clicking on **Restore NuGet packages...** ![Restore NuGets](http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/a31a6bff-b45d-4c60-a602-1359f984e80b/2016-07-11_1328.png) ### Model We will be pulling down information about speakers. Open the **DevDaysSpeakers/Model/Speaker.cs** file and add the following properties inside of the **Speaker** class: ```csharp public string Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string Website { get; set; } public string Title { get; set; } public string Avatar { get; set; } ``` ### View Model The **SpeakersViewModel.cs** will provide all of the functionality for how our main Xamarin.Forms view will display data. It will consist of a list of speakers and a method that can be called to get the speakers from the server. It will also contain a boolean flag that will indicate if we are getting data in a background task. #### Implementing INotifyPropertyChanged *INotifyPropertyChanged* is important for data binding in MVVM Frameworks. This is an interface that, when implemented, lets our view know about changes to the model. Update: ```csharp public class SpeakersViewModel { } ``` to ```csharp public class SpeakersViewModel : INotifyPropertyChanged { } ``` Simply right click and tap **Implement Interface**, which will add the following line of code: ```csharp public event PropertyChangedEventHandler PropertyChanged; ``` We will code a helper method named **OnPropertyChanged** that will raise the **PropertyChanged** event (see below). We will invoke the helper method whenever a property changes. ##### C# 6 (Visual Studio 2015 or Xamarin Studio on Mac) ```csharp void OnPropertyChanged([CallerMemberName] string name = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); ``` ##### C# 5 (Visual Studio 2012 or 2013) ```csharp void OnPropertyChanged([CallerMemberName] string name = null) { var changed = PropertyChanged; if (changed == null) return; changed.Invoke(this, new PropertyChangedEventArgs(name)); } ``` Now, we can call **OnPropertyChanged();** whenever a property updates. Let's create our first property now. #### IsBusy We will create a backing field and accessors for a boolean property. This will let our view know that our view model is busy so we don't perform duplicate operations (like allowing the user to refresh the data multiple times). First, create the backing field: ```csharp bool busy; ``` Next, create the property: ```csharp public bool IsBusy { get { return busy; } set { busy = value; OnPropertyChanged(); } } ``` Notice that we call **OnPropertyChanged();** whenever the value changes. The Xamarin.Forms binding infrastructure will subscribe to our **PropertyChanged** event so the UI will get notified of the change. #### ObservableCollection of Speaker We will use an **ObservableCollection** that will be cleared and then loaded with speakers. We will use an **ObservableCollection** because it has built-in support for **CollectionChanged** events when we Add or Remove from it. This is very nice so we don't have to call **OnPropertyChanged** each time. In the class above the constructor declare an auto-property: ```csharp public ObservableCollection Speakers { get; set; } ``` Inside of the constructor, create a new instance of the `ObservableCollection`: ```csharp public SpeakersViewModel() { Speakers = new ObservableCollection(); } ``` #### GetSpeakers Method We are now set to create a method named **GetSpeakers** which will retrieve the speaker data from the internet. We will first implement this with a simply HTTP request, but later update it to grab and sync the data from Azure! First, create a method called **GetSpeakers** which is of type *async Task* (it is a Task because it is using Async methods): ```csharp async Task GetSpeakers() { } ``` The following code will be written INSIDE of this method: First is to check if we are already grabbing data: ```csharp async Task GetSpeakers() { if(IsBusy) return; } ``` Next we will create some scaffolding for try/catch/finally blocks: ```csharp async Task GetSpeakers() { if (IsBusy) return; Exception error = null; try { IsBusy = true; } catch (Exception ex) { error = ex; } finally { IsBusy = false; } } ``` Notice, that we set *IsBusy* to true and then false when we start to call to the server and when we finish. Now, we will use *HttpClient* to grab the json from the server inside of the **try** block. ```csharp using(var client = new HttpClient()) { //grab json from server var json = await client.GetStringAsync("http://demo4404797.mockable.io/speakers"); } ``` Still inside of the **using**, we will Deserialize the json and turn it into a list of Speakers with Json.NET: ```csharp var items = JsonConvert.DeserializeObject>(json); ``` Still inside of the **using**, we will clear the speakers and then load them into the ObservableCollection: ```csharp Speakers.Clear(); foreach (var item in items) Speakers.Add(item); ``` If anything goes wrong the **catch** will save the exception and AFTER the finally block we can pop up an alert: ```csharp if (error != null) await Application.Current.MainPage.DisplayAlert("Error!", error.Message, "OK"); ``` The completed code should look like: ```csharp async Task GetSpeakers() { if (IsBusy) return; Exception error = null; try { IsBusy = true; using(var client = new HttpClient()) { //grab json from server var json = await client.GetStringAsync("http://demo4404797.mockable.io/speakers"); //Deserialize json var items = JsonConvert.DeserializeObject>(json); //Load speakers into list Speakers.Clear(); foreach (var item in items) Speakers.Add(item); } } catch (Exception ex) { Debug.WriteLine("Error: " + ex); error = ex; } finally { IsBusy = false; } if (error != null) await Application.Current.MainPage.DisplayAlert("Error!", error.Message, "OK"); } ``` Our main method for getting data is now complete! #### GetSpeakers Command Instead of invoking this method directly, we will expose it with a **Command**. A Command has an interface that knows what method to invoke and has an optional way of describing if the Command is enabled. Create a new Command called **GetSpeakersCommand**: ```csharp public Command GetSpeakersCommand { get; set; } ``` Inside of the `SpeakersViewModel` constructor, create the `GetSpeakersCommand` and pass it two methods: one to invoke when the command is executed and another that determines whether the command is enabled. Both methods can be implemented as lambda expressions as shown below: ```csharp GetSpeakersCommand = new Command( async () => await GetSpeakers(), () => !IsBusy); ``` The only modification that we will have to make is when we set the IsBusy property, as we will want to re-evaluate the enabled function that we created. In the **set** of **IsBusy** simply invoke the **ChangeCanExecute** method on the **GetSpeakersCommand** as shown below: ```csharp set { busy = value; OnPropertyChanged(); //Update the can execute GetSpeakersCommand.ChangeCanExecute(); } ``` ## The User Interface!!! It is now finally time to build out our first Xamarin.Forms user interface in the **View/SpeakersPage.xaml** ### SpeakersPage.xaml For the first page we will add a few vertically-stacked controls to the page. We can use a StackLayout to do this. Between the `ContentPage` tags add the following: ```xml ``` This will be the container where all of the child controls will go. Notice that we specified the children should have no space in between them. Next, let's add a Button that has a binding to the **GetSpeakersCommand** that we created (see below). The command takes the place of a clicked handler and will be executed whenever the user taps the button. ```xml