PTXug – Xamarin Talks #2

Event Details

No dia 27-06-2015 será realizada a PTXug – Xamarin Talk #2 em Lisboa. Para participar, efectue o registo de acordo com as instruções abaixo.

Agenda

09:45  – Recepção dos participantes
10:00  – Arquitectura e técnicas para uma app portável -‏ Diogo Cardoso
 Com o sucesso doXamarin, fazerapps portáveis tornou-se mais fácil, mas fazê-lo de forma correcta e de aproveitar o máximo código possível não é algo tão simples como parece.Nesta sessão irei abordar a arquitectura que utilizo nas apps ImaginationOverflow, bem como as estratégias e métodos que tornam estas mesmas apps portáveis.
11:00  – Intervalo
11:30  –  TDD for what? It just works fine on MY machine – Jorge André Alves
 Nesta talk o Jorge vai abordar o conceito de TDD, quais as vantagens e as possíveis desvantagens para quem quiser começar. Por fim irá aborda os testes unitários usando NUnit e falar-nos da sua experiência.
12:30  – Sorteio de Prémios
Nota: Ao final da reunião, escolhemos um restaurante próximo e fazemos um almoço em grupo para continuar o convívio e aproximar as pessoas. A participação é opcional.


Registrar aquiptxug-tx2.eventbrite.com

Local

MAIN HUB – Innovation, Incubation & Development ( junto à estação de metro Cabo Ruivo)
Avenida Pádua 10A
1800-297 Lisboa
Portugal


Patrociníos

 

 

Windows 10 Developer Readiness – Powered by MVPs

Windows 10 Dev Readiness
  #Win10MVP


About
We’re excited to offer a series of live webcasts that deliver first-hand guidance on how you can leverage the new Windows 10 development model. The webcasts will be presented and moderated by Microsoft MVPs around the world at no charge and are a great opportunity for you to not only learn the foundations of Universal App Development in Windows 10, but also to connect with some of the top experts in your country and/or language. Bring your Windows Store app development questions and have them answered live, by the experts, and learn how to take advantage of the great opportunities ahead in the Universal Windows Platform.
  • Each webcast will deliver the same content in different countries from June 8 – 12.
  • They will last from one to three hours, depending on the amount of community interaction.
Microsoft is empowering the MVPs with technical content and private training so every session will be fully equipped with content, demos, and up-to-date guidance.
We hope you join and connect with us for this great worldwide initiative!


Agenda & Registration
Webcast Title: Windows 10 Developer Readiness – Powered by MVPs
Description: Join the Microsoft MVPs in this live webcast to learn how to build or bring your app to the *NEW* Universal Windows Platform (UWP)! We will show the foundation, demo advanced features, and answer your app development questions so you take advantage of the opportunities ahead with the Universal Windows Platform.

In Portugal, Sara Silva and Alexandre Marreiros will delivery the presentation at June 12nd – 08:00 pm, register in this reference.

Palestra Xamarin – Universidade Nova de Lisboa

xamarim    As aplicações móveis estão muito na moda, e daí que tantos de nós já tenham tido N ideias para uma aplicação móvel. Também muitos programadores decerto que já se aventuraram a criar pelo menos uma app. E agora uma questão muito importante: para que plataforma desenvolveram? Android? iOS? Windows? … 3 Apps? … 3 Linguagens de programação? Nesta sessão, a Sara irá apresentar a Xamarin e os seus produtos. Irá também explicar em que consiste o desenvolvimento de aplicações cross-platform usando Xamarin, quais as boas práticas que se devem seguir e de que forma se deve reutilizar o código para que no final não acabe numa app cheia de “Spaghetti”. Aproveita esta sessão para começares a utilizar mais uma plataforma que é inteiramente grátis para estudantes!

Ver mais em: http://www.revista-programar.info/artigos/xamarin-sem-custos-para-estudantes/.

Não percas esta oportunidade, reserva já o teu lugar: http://goo.gl/PAGfQD

#PGGD27 – 27º Portugal Girl Geek Dinner – Lisboa

O próximo encontro em Lisboa vai contar com a Cláudia e a Ekaterina e vais poder aprender mais sobre OData e machine learning!

Os lugares são limitados! Inscreve-te aqui!
Agenda:

19:00 Registo / Snacks & Drinks

19:30 Boas-vindas

19:40 Ekaterina Stambolieva – What can machine learning do for businesses?

Ekaterina is very passionate and interested in machine learning and its real-world applications. She will introduce us to the machine learning world, speak about why and how companies apply it, and tell us what skills we need to develop to become machine learning experts.

20:20 Cláudia Carvalho – OData – The Protocol for REST APIs

OData is currently a standard way to create a REST API. In this session, Cláudia will introduce us to the potentials and benefits of ODATA and the simplicity behind the creation of an OData Server. Finally, we will learn more about OData queries and operations for any kind of ODATA server.

21:00 Encerramento

Como chegar ao ISCTE-IUL e ao Auditório 0NE01.

Apoio:

ISCTE-IUL ACM

PTXug – Xamarin Workshop #1

Event Details

No dia 30-05-2015 será realizada a PTXug – Xamarin Talk #1 em Lisboa. Para participar, efectue o registo de acordo com as instruções abaixo.

Agenda

14:45  – Recepção dos participantes
15:00  –  Criação de ambiente de desenvolvimento para Windows & Mac – Sara Silva
 Este Workshop será focado na criação de ambiente de desenvolvimento em Windows/Mac, detalhando as várias ferramentas e SDKs que deverão ser instalados.
17:00  –  Sorteio de Prémios
Requisitos: cada participante deverá ter conhecimentos de programação (C#, Java ou Objective-C/Swift preferencialmente) e trazer um portátil Windows ou Mac.

Local

MAIN HUB – Innovation, Incubation & Development ( junto à estação de metro Cabo Ruivo)
Avenida Pádua 10A
1800-297 Lisboa
Portugal


Patrociníos

 

PTXug – Xamarin Talks #1

Event Details

No dia 30-05-2015 será realizada a PTXug – Xamarin Talk #1 em Lisboa. Para participar, efectue o registo de acordo com as instruções abaixo.

Agenda

09:45  – Recepção dos participantes
10:00  – await Xamarin() – Paulo Morgado
11:00  – Intervalo
11:30  – WCF em desenvolvimento cross-platform usando Xamarin – João Cardoso
12:30  – Sorteio de Prémios
Nota: Ao final da reunião, escolhemos um restaurante próximo e fazemos um almoço em grupo para continuar o convívio e aproximar as pessoas. A participação é opcional.

Local

MAIN HUB – Innovation, Incubation & Development ( junto à estação de metro Cabo Ruivo)
Avenida Pádua 10A
1800-297 Lisboa
Portugal


Patrociníos

 

Xamarin Guide 11: Create a LoginView

Scope

This Xamarin Workshop Guide was created for the The Portuguese National Meeting of IT Students (ENEI) by Sara Silva which original content is available here. With the goal to extend it to the global community, it was published in a new project called Xam Community Workshop, which the main goal is to any developer, or user group customize it to theirs events.

11. Create a LoginView

In this step you will learn how to create the user interface to the LoginView using the Font Awesome, how to create the LoginViewModel and how to handle the navigation between pages.

Creating the UI using Font Awesome

The Font Awesome support icons which can be displayed using a Label, this way is possible to use this font to show icon in the application. In this step you will use the Microsoft, Google and Facebook icons to display in the UI, this way you do not need to use images.

To start, open the ENEI.SessionsApp project and add a new XAML page in the Views folder, as following:

Figure 55: Creating LoginView

Figure 55: Creating LoginView

The result will be the following XAML page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="ENEI.SessionsApp.Views.LoginView">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

Now, you can define the user interface, but before it you need to do some additional tasks, in each platform to make sure the font will be displayed in the screen when you run the app. In general you need:

  • In ENEI.SessionsApp.iOS
    • Add the FontAwesome.ttf file to Resources folderFigure 56: The Resources folder

      Figure 56: The Resources folder

    • Change the Info.plist, to include the font

In Visual Studio or Xamarin Studio is possible to edit the xml as following:

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
   <dict>

   …

   <key>UIAppFonts</key>
    <array>
    <string>FontAwesome.ttf</string>
   </array> 
</dict>
</plist>

In Xamarin Studio you can add the font as following:

Figure 57: The Source panel from Info.plist in Xamarin Studio

Figure 57: The Source panel from Info.plist in Xamarin Studio

  • In ENEI.SessionsApp.Android
    • Add the FontAwesome.ttf to the Assets folderFigure 58: The Assets folder

      Figure 58: The Assets folder

    • Create a Render for a CustomLabel
  • [assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRenderer))]
    namespace ENEI.SessionsApp.Droid.Renders
    {
       public class CustomLabelRenderer: LabelRenderer
       {
           protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
          {
    base.OnElementChanged(e);
    
    var label = (TextView)Control;
    Typeface font = Typeface.CreateFromAsset(Forms.Context.Assets, "FontAwesome.ttf");
    label.Typeface = font;
          }
       }
    }
  • In ENEI.SessionsApp.WinPhone and ENEI.SessionsApp.WinRT
    • Add the FontAwesome.ttf to the Assets/Fonts folderFigure 59: The Assets/Folder folder

      Figure 59: The Assets/Folder folder

    • Set the FontAwesome.ttf as Content and Copy AlwaysFigure 60: Configurations

      Figure 60: Configurations

• In ENEI.SessionsApp

  • Add a CustomLabel class
  • Define the FontFamily for each platform
  • public class CustomLabel : Label
    {
        public CustomLabel()
        {
          FontFamily = Device.OnPlatform(
           iOS: "FontAwesome", 
           Android: null,
           WinPhone:@"\Assets\Fonts\FontAwesome.ttf#FontAwesome");
    
        if (Device.OS == TargetPlatform.Windows)
        {
            FontFamily = @"\Assets\Fonts\FontAwesome.ttf#FontAwesome";
        }
       }
    }

Now you are ready to create the UI for the LoginView. The base for the page can be something as following:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:controls="clr-namespace:ENEI.SessionsApp.Controls;assembly=ENEI.SessionsApp"
         x:Class="ENEI.SessionsApp.Views.LoginView"
         Title="Authentication" BackgroundColor="White" x:Name="ContentPage"
         Icon="ic_action_users.png">

         <Grid BackgroundColor="White">
         <Grid.RowDefinitions>
           <RowDefinition Height="Auto" />
           <RowDefinition Height="*" />
         </Grid.RowDefinitions>
         <!-- Title - Only for WP-->
        <StackLayout Grid.Row="0" Orientation="Horizontal" Padding="20,10,0,0">
        <StackLayout.IsVisible>
           <OnPlatform Android="false" WinPhone="true" iOS="false"
                x:TypeArguments="x:Boolean" />
        </StackLayout.IsVisible>
        <Image WidthRequest="48"
             HeightRequest="38"
             Source="Images/ic_action_users.png"/>
        <Label FontSize="Medium" FontAttributes="Bold"
           TextColor="Black">
            <OnPlatform Android="" WinPhone="Authentication"
                iOS="" x:TypeArguments="x:String" />
        </Label>
      </StackLayout>
  <StackLayout Spacing="20" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Grid.Row="1"> 
           <!—login by social network will be here -->
</StackLayout>

Then you can define options for login with Facebook, Google or Microsoft as following:

  • Facebook
  • <StackLayout WidthRequest="300" HeightRequest="60" Orientation="Horizontal" BackgroundColor="#3b5998" HorizontalOptions="Center" Spacing="20">
    <controls:CustomLabel FontSize="Small"
                        HorizontalOptions="CenterAndExpand"
                        Text=""
                        TextColor="White"
                        VerticalOptions="CenterAndExpand" />
    <Label FontAttributes="Bold"
            FontSize="Small"
            HorizontalOptions="StartAndExpand"
            Text="Facebook"
            TextColor="White"
            VerticalOptions="CenterAndExpand" />
    </StackLayout>
  • Google
  • <StackLayout WidthRequest="300" HeightRequest="60"  Orientation="Horizontal" BackgroundColor="#dd4b39" HorizontalOptions="Center" Spacing="20">
      <controls:CustomLabel FontSize="Small"
                          HorizontalOptions="CenterAndExpand"
                          Text=""
                          TextColor="White"
                          VerticalOptions="CenterAndExpand" />
      <Label FontAttributes="Bold"
            FontSize="Small"
            HorizontalOptions="StartAndExpand"
            Text="Google"
            TextColor="White"
            VerticalOptions="CenterAndExpand" />
    </StackLayout>
  • Microsoft
  • <StackLayout WidthRequest="300" HeightRequest="60"  Orientation="Horizontal" BackgroundColor="#219dfd" HorizontalOptions="Center" Spacing="20">
    <controls:CustomLabel FontSize="Small"
                       HorizontalOptions="CenterAndExpand"
                       Text=""
                       TextColor="White"
                       VerticalOptions="CenterAndExpand" />
    <Label FontAttributes="Bold"
           FontSize="Small"
           HorizontalOptions="StartAndExpand"
           Text="Microsoft"
           TextColor="White"
           VerticalOptions="CenterAndExpand" />
    </StackLayout>

When you run the application the result will something as described in figure 61:

Figure 61: The LoginView

Figure 61: The LoginView

See more details about this subject in the following references: Working with Fonts and FontAwesome Library for Xamarin.iOS (MonoTouch).

Create the LoginViewModel

At this moment, you have the user interface to the LoginView, this way it is possible to define the LoginViewModel, which will have the action to each option in LoginView.

Open the ENEI.SessionsApp project and add the LoginViewModel to the ViewModels folder, as following:

Figure 62: The LoginViewModel

Figure 62: The LoginViewModel

Then create the LoginCommnad, as following:

public class LoginViewModel
{
    public LoginViewModel()
    {
        LoginCommand =new Command(DoLogin);
    }

    private void DoLogin(object param)
    {
        var option = param.ToString();
        switch (option)
        {
            case "facebook":
             //connect with facebook api
                break;
            case "goolge":
             //connect with google api
                break;
            case "microsoft":
             //connect with microsoft api
                break;
        }
    }

    public ICommand LoginCommand { get; set; }
}

In this case, you only created one ICommand that will be used be all options in the LoginView and for it is required to send as CommandParameter the name of the option, as we will see next.

Now, connect the UI with the LoginViewModel and to start, define the LoginViewModel and binding it to the BindingContext as following:

public partial class LoginView : ContentPage
{
    public LoginView()
    {
        InitializeComponent();
        BindingContext = new LoginViewModel();
    }
}

Then change the StackLayout that is the root for each option as following:

  <StackLayout WidthRequest="300" HeightRequest="60" Orientation="Horizontal" BackgroundColor="#3b5998" HorizontalOptions="Center" Spacing="20">
     <StackLayout.GestureRecognizers>
          <TapGestureRecognizer CommandParameter="facebook"
                                Command="{Binding LoginCommand}"/>
      </StackLayout.GestureRecognizers>
    <controls:CustomLabel FontSize="Small"
                        HorizontalOptions="CenterAndExpand"
                        Text=""
                        TextColor="White"
                        VerticalOptions="CenterAndExpand" />
    <Label FontAttributes="Bold"
            FontSize="Small"
            HorizontalOptions="StartAndExpand"
            Text="Facebook"
            TextColor="White"
            VerticalOptions="CenterAndExpand" />
  </StackLayout>

Do a similar implementation to the others option. When you run the application you should call the DoLogin method, as following:

Figure 63: The DoLogin method in debug mode

Figure 63: The DoLogin method in debug mode

Handle Navigation

At this moment you do not have the authentication, but you can create the complete flow to the application. This way, you need to define the navigation between pages, which is the main goal of this step.

To start, you can create a NavMessage, as following:

public class NavMessage
{
    public string Page { get; set; }

    public object Param { get; set; }
}

Then, in the App class you can use MessaginCenter to navigate between pages, as following:

    public App()
    {
        InitializeComponent();
        MainPage = new NavigationPage(new LoginView())
        {
            BarBackgroundColor = Color.White,
            BarTextColor = Color.Black,
            BackgroundColor = Color.White,
        };

        MessagingCenter.Subscribe<NavMessage>(this, "Navigation", navMessage =>
        {
            switch (navMessage.Page)
            {
                case "login":
                    MainPage = new LoginView();
                    break;
                case "sessions":
                    MainPage = new NavigationPage(new SessionsView())
                    {
                        BarBackgroundColor = Color.White,
                        BarTextColor = Color.Black,
                        BackgroundColor = Color.White,
                    };
                    break;
                case "details":
                    MainPage.Navigation.PushAsync(new SessionDetailsView(navMessage.Param as Session), true);
                    break;
            }
        });
    }

There are different way to handle the navigation and it can be defined based in the application requirements.

In the LoginViewModel you should change the DoLogin method to:

private void DoLogin(object param)
    {
        var option = param.ToString();
        switch (option)
        {
            case "facebook":
             //connect with facebook api
                break;
            case "goolge":
             //connect with google api
                break;
            case "microsoft":
             //connect with microsoft api
                break;
        }
        MessagingCenter.Send(new NavMessage{ Page = "sessions"}, "Navigation");
    }

At this moment is not important the authentication, because that feature will be focused in nexts steps.

In the SessionsViewModel change the SeeSessionDetails method to:

 

And, in the SessionsView remove the navigation, which result should be:

  public SessionsView()
  {
     InitializeComponent();
  }

At this moment if you run the application you should start in the LoginView and then you can see the SessionsView and the SessionDetailsView.

Xamarin Guide 10: Move ItemTemplate to Resources

Scope

This Xamarin Workshop Guide was created for the The Portuguese National Meeting of IT Students (ENEI) by Sara Silva which original content is available here. With the goal to extend it to the global community, it was published in a new project called Xam Community Workshop, which the main goal is to any developer, or user group customize it to theirs events.

10. Move ItemTemplate to Resources

In the last two step you learned to create an App class using XAML approach and how to use MVVM pattern, to separate the UI to the logic. In this step you learn how extract the DataTemplate from the listview’s Itemtemplate to Resources.

In the App.xaml prepare the code to add the DataTemplate, for it you need to define the Application’s Resources as following:

 <!--?<span class="hiddenSpellError" pre="" data-mce-bogus="1"-->xml version="1.0" encoding="utf-8" ?&gt;
 
 
   

   
 

And then copy the DataTemplate defined inside the ListView’s ItemTemplate:

&lt;ListView x:Name="SessionsList"
           Grid.Row="1"
           RowHeight="{Binding Converter={StaticResource RowHeightConverter}}"
           ItemSelected="SessionsList_OnItemSelected"
           ItemsSource="{Binding Sessions}"
           SeparatorColor="#0094FF"&gt;
 
   
    <!--—this DataTemplate---->
   

To inside the ResourceDictionary, as following:

<!--?<span class="hiddenSpellError" pre="" data-mce-bogus="1"-->xml version="1.0" encoding="utf-8" ?&gt;

 
  
    
      
        
         
          
            
            
          
          
            
            
            
            
          
          <img alt="" />
            
              
            
            
              
            
          
          

            <label>

            <label>
            <label>
          </label></label></label>

               ….

  
  
 

Then, define the x:key value to identify the DataTemplate as following:

 <Application.Resources>
    <ResourceDictionary>
      <DataTemplate x:Key="SessionTemplate">

If you run the application you will get some errors because it is required to move the converters and theSessionViewModel to App.xaml, as following:

  …

 
   
     <viewModels:SessionViewModel x:Key="SessionViewModel"/>
     
     
     
     
        

 ….

Now you can use the DataTemplate defined in Resources, using the key defined “SessionTemplate”, as following:

   <!-- ListView will be defined here -->
   <ListView x:Name="SessionsList"
               Grid.Row="1"
               RowHeight="{Binding Converter={StaticResource RowHeightConverter}}"
               ItemSelected="SessionsList_OnItemSelected"
               ItemsSource="{Binding Sessions}"
               SeparatorColor="#0094FF" ItemTemplate="{StaticResource SessionTemplate}">

This way, the SessionsView.xaml looks cleaner, it is easier to understand the code and is possible to reuse the DataTemplate if needed.

Xamarin Guide 9: Use MVVM pattern

Scope

This Xamarin Workshop Guide was created for the The Portuguese National Meeting of IT Students (ENEI) by Sara Silva which original content is available here. With the goal to extend it to the global community, it was published in a new project called Xam Community Workshop, which the main goal is to any developer, or user group customize it to theirs events.

9. Use MVVM pattern

In this step you will learn how refactor your code to use the MVVM pattern.

“The Model-View-ViewModel (MVVM) pattern helps you to cleanly separate the business and presentation logic of your application from its user interface (UI). Maintaining a clean separation between application logic and UI helps to address numerous development and design issues and can make your application much easier to test, maintain, and evolve. It can also greatly improve code re-use opportunities and allows developers and UI designers to more easily collaborate when developing their respectiv e parts of the application.”

in MSDN

To help understand the MVVM pattern, here is a diagram which explain how it works:

MVVM Pattern diagram

Figure 53: MVVM Pattern diagram

In the Sessions App, you can create two view models, one for each page. To help matching views and view models, in general you should have:

  • SessionsView will be connected with SessionViewModel
  • SessionDetailsView will be connected with SessionDetailsViewModel

Usually all view models are defined in a ViewModels folders, this way any developers will recognize that the application uses MVVM pattern and it is easy to match Views and ViewModels (but any developer is free to organize the application based in application requirements!).

Let’s create the view models!

In ENEI.SessionsApp project, create a folder called ViewModels, and then create the class SessionViewModel. The result should be something as following:

MVVM Pattern diagram

Figure 54: The view model folder

Now you need to refactor the code in SessionView.xaml.cs. For it let’s define the SessionViewModel class as following:

public class SessionViewModel
{
    public SessionViewModel()
    {
        Sessions = new ObservableCollection(); 
    }

    public ObservableCollection Sessions { get; set; }

    public async Task LoadDataAsync()
    {
       await Task.Run(() =>
        {
            if (Sessions.Count == 0)
            {
                var sessions = SessionsDataSource.GetSessions();
                foreach (var session in sessions)
                {
                    Sessions.Add(session);
                }
            }
        });
    }
}

This way, you defined the Sessions list and the LoadDataAsync in ViewModel, now you need to create the command for each option in the menu.

In the SessionsView.xaml.cs you have the event’s handler from the Tap event (for Like, Favorite, Share and SessionDetails) which are defined in Xaml as following:

  <TapGestureRecognizer x:Name="DetailsGesture"
                    CommandParameter="{Binding}"
                    Tapped="DetailsGesture_OnTapped" />

These event’s handle are not friendly for who want implement MVVM pattern, to solve it was create the “ICommand” that allow to call the associate action. This way we need to define the ICommand for each option as following:

public ICommand LikeCommand { get; private set; }
public ICommand FavoriteCommand { get; private set; }
public ICommand ShareCommand { get; private set; }
public ICommand SessionDetailsCommand { get; private set; }

And in the constructor is required to initialize each one, as following:

 public SessionViewModel()
    {
        Sessions = new ObservableCollection();
        LikeCommand = new Command(ApplyLike);
        FavoriteCommand = new Command(ApplyFavorite);
        ShareCommand = new Command(Share);
        SessionDetailsCommand = new Command(SeeSessionDetails);
    }

Where each method above is defined by:

  • ApplyLike
  • private void ApplyLike(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            session.NumLikes++;
        }
    }
  • ApplyFavorite
  • private void ApplyFavorite(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            session.IsFavorite = !session.IsFavorite;
        }
    }
  • Share
  • private void Share(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            var shareService = DependencyService.Get();
            if (shareService != null)
            {
                var status = string.Format("Não percas a sessão {0} de {1}.", session.Name, session.Speaker.Name);
                shareService.ShareLink("ENEI 2015", status, "https://enei.pt/");
            }
        }
    }
  • SeeSessionDetails
  • private void SeeSessionDetails(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            MessagingCenter.Send(session, "SeeSessionDetails");
        }
    }

The MessagingCenter is a class that has the capability to send and receive message. In this case, when a user wants to see the session details the view model will send a message with the session to the view, and then the view will navigate to the SessionDetailsView.

See more about Publish and Subscribe with MessagingCenter.

At the end your SessionViewModel class should be defined as following:

public class SessionViewModel
{
    public SessionViewModel()
    {
        Sessions = new ObservableCollection();
        LikeCommand = new Command(ApplyLike);
        FavoriteCommand = new Command(ApplyFavorite);
        ShareCommand = new Command(Share);
        SessionDetailsCommand = new Command(SeeSessionDetails);
    }

    public ObservableCollection Sessions { get; set; }
    public ICommand LikeCommand { get; private set; }
    public ICommand FavoriteCommand { get; private set; }
    public ICommand ShareCommand { get; private set; }
    public ICommand SessionDetailsCommand { get; private set; }

    private void ApplyLike(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            session.NumLikes++;
        }
    }

    private void ApplyFavorite(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            session.IsFavorite = !session.IsFavorite;
        }
    }

    private void Share(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            var shareService = DependencyService.Get();
            if (shareService != null)
            {
                var status = string.Format("Não percas a sessão {0} de {1}.", session.Name, session.Speaker.Name);
                shareService.ShareLink("ENEI 2015", status, "https://enei.pt/");
            }
        }
    }

    private void SeeSessionDetails(object param)
    {
        var session = param as Session;
        if (session != null)
        {
            MessagingCenter.Send(session, "SeeSessionDetails");
        }
    }

    public async Task LoadDataAsync()
    {
       await Task.Run(() =>
        {
            if (Sessions.Count == 0)
            {
                var sessions = SessionsDataSource.GetSessions();
                foreach (var session in sessions)
                {
                    Sessions.Add(session);
                }
            }
        });
    }
}

And the SessionsView.xaml.cs should be changed to:

public partial class SessionsView : ContentPage
{
    public SessionsView()
    {
        InitializeComponent();
        MessagingCenter.Subscribe(this, "SeeSessionDetails", session =>
        {
            Navigation.PushAsync(new SessionDetailsView(session), true);
        });
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        var viewmodel = BindingContext as SessionViewModel;
        if (viewmodel != null)
        {
            await viewmodel.LoadDataAsync();
        }
    }

    private void SessionsList_OnItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        //workarround to clean the select item
        if (SessionsList.SelectedItem == null)
        {
            return;
        }

        SessionsList.SelectedItem = null;
    }
}

The event’s handler SessionsList_OnItemSelected will not be changed, because it is a workaround to clean the selected item.

In the SessionsView.xaml is required to do few changes:

  • Define the SessionViewModel as a resource from the page
  • <ContentPage.Resources>
       
    
  • Binding the SessionViewModel to the BindingContext from the view
  • xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:converters="clr-namespace:ENEI.SessionsApp.Converters;assembly=ENEI.SessionsApp"
         xmlns:viewModels="clr-namespace:ENEI.SessionsApp.ViewModels;assembly=ENEI.SessionsApp"
         x:Class="ENEI.SessionsApp.Views.SessionsView"
         Title="1010 ENEI || Sessões"
         BackgroundColor="White" 
         x:Name="ContentPage" 
         BindingContext="{StaticResource SessionViewModel}"
         Icon="ic_action_users.png">
  • For each option change the TapGestureRecognizer
  •  <TapGestureRecognizer 
       CommandParameter="{Binding}" 
       Command="{Binding SessionDetailsCommand, Source={StaticResource SessionViewModel}}"/>

The Command is binding to the respective command from the view model, but each developer should be aware that when the view is loaded the binding context from the Image is defined with a Session from the respective listview’s item. For this reason is required to define the binding’s Source, which uses the view model as a static resource (at this moment is not possible to apply relative binding and is not good practice to define the commands in the model object because it belong to the view model!).

If you run the application it must behave as before.

It is possible to define the view model to the SessionDetailsView, but because it only show a Session and do not have any other capability is not important that change it.

To learn more about this subject is recommend to read the following articles: XAML Basics Contents