Tag Archives: mvvm

Agile@School – settima lezione

Settimo appuntamento presso la scuola rodigina IIS Viola/Marchesini per il progetto Agile@School nella giornata di ieri 24 gennaio 2018. Si è giunti alla parte finale dove cerchiamo di mettere insieme tutte le parti finora studiate. Ci siamo dati come obiettivo quello di realizzare una semplice app per l’accesso a Twitter mettendo in gioco le conoscenze apprese.

1.png Continue reading Agile@School – settima lezione

Agile@School – Terza lezione

Eccoci giunti alla terza lezione su dieci del laboratorio Agile@School dell’IIS Viola/Marchesini di Rovigo

Screenshot_1

Stand-up meeting

Anche questa volta abbiamo fatto pratica con lo stand-up meeting in cui abbiamo fatto un piccolo riassunto della puntata precedente ed è stato introdotto a grandi linee il programma della giornata. La partecipazione al riassunto sugli argomenti passati è stata tiepida ma ugualmente ci ha fatto scontrare col fatto che per riassumere gli episodi precedenti bisogna scegliere l’adeguato livello di astrazione: né troppo elevato, né troppo dettagliato. A seguire ho introdotto gli argomenti della giornata e una previsione sulla lezione futura.

MVVM – Comandi

Abbiamo ripreso il filo della lezione precedente introducendo il concetto di comandi nel mondo MVVM. Con l’occasione abbiamo letto insieme la documentazione MSDN dell’interfaccia ICommand, abbiamo ripassato il concetto di delegati e studiato un’implementazione di ICommand. Ancora una volta il livello di preparazione delle quinte mi ha stupito perché la definizione di delegato era già stata spiegata dai prof. nelle ore “standard”, cose che ai miei tempi non si facevano.

Hands-on

Per impratichirsi coi comandi ai ragazzi è stata consegnata un’applicazione già iniziata ma con delle parti mancanti. Abbiamo preso questa occasione per riconciliare tutte le cose provate nelle puntate precedenti e quindi abbiamo:

  • Creato un nuovo progetto su VSTS;
  • Inizializzato il repository git con l’applicativo di base;
  • Ho fatto finta di essere un cliente che racconta un’esigenza che è stata trascritta dagli studenti in forma di user story in VSTS;
  • Sviluppato su feature-branch collegato alla user-story;
  • Creato pull-request e fatto merge del lavoro.

Quello che qui è riassunto in cinque punti di un elenco puntato è stato ricco di interazione tra me e la classe e tra gli studenti stessi. Confronti, dubbi, errori, chi finiva priva che spiegava agli altri…

A questo punto la classe mi ha nuovamente stupito perché hanno finito in anticipo rispetto alle tempistiche che avevo immaginato e quindi mi sono dovuto inventare al volo un’altra esigenza e abbiamo ripetuto di nuovo il processo di sviluppo. Già al secondo giro si vedeva una maggiore confidenza sia con VSTS che con il pattern MVVM.

Wrap-up

Anche questa volta una giornata positiva e sicuramente la più operativa in termini d’uso di VSTS e righe di codice.

Nella prossima lezione approderemo su Xamarin facendo una panoramica sui concetti base.

Alla prossima settimana!

Agile@School – Seconda lezione

Anche questa settimana si è svolto l’incontro del laboratorio Agile@School all’IIS Viola/Marchesini.

Stand-up meeting

In questa seconda lezione abbiamo applicato subito uno dei concetti affrontati la lezione scorsa: il feedback per incentivare il miglioramento continuo. Ne abbiamo approfittato per introdurre lo stand-up meeting che viene svolto da molti team. In questi minuti di  incontro “informale” in piedi abbiamo provato a raccogliere sensazioni e pareri sul primo incontro. Dopo un primo momento di silenzio qualcuno ha detto il proprio parere:

  • Alcuni hanno definito l’incontro più interessante del previsto, in particolare è stato trovato interessante il concetto di team e la sua gestione;
  • Qualcun’altro è stato colpito dalla potenza della visualizzazione del lavoro tramite una kanban board;
  • Uno dei professori ha riferito che i principi base riguardanti DevOps sono molto interessanti.

Ho provato anche a incentivare feedback negativi ma nessuno si è sbilanciato. Per ora 3 feedback positivi sono un buon risultato, avanti così!

Sempre per esercitarci sullo stand-up meeting abbiamo anche accennato gli argomenti che avremmo affrontato nel pomeriggio e quelli della prossima lezione.

Slack

Per prendere confidenza con gli strumenti di collaborazione più diffusi ci siamo inseriti nell team Slack agileschool.slack.com. I ragazzi si sono trovati subito a loro agio senza problemi. Useremo Slack per passarci esercizi e il materiale che di volta in volta riterremo necessario.

Pull-Request

Tornati seduti abbiamo lavorato con VSTS per esercitarci con le pull-request. Gli studenti sono stati suddivisi in team da tre persone che hanno lavorato su un semplice esercizio con un’app WPF già preparata a cui apportare piccole modifiche. Alla fine del lavoro si chiedeva un’approvazione tramite PR agli altri membri del team. Con alcuni team ci siamo scontrati con problemi di merge. In alcuni casi li abbiamo risolti, in altri non ce l’abbiamo fatta per motivi di tempo.
Ad ogni modo mi sembra che il concetto e a cosa servono le pull-request sia stato ben capito.

MVVM

Come ultimo argomento abbiamo introdotto le basi dell’MVVM, il noto pattern a tre livelli per strutturare app che verrà utile con Xamarin Forms.

Abbiamo svolto un esercizio che ci ha fatto mettere le mani e vedere funzionare i meccanismi alla base di questo template e in particolare ci siamo concentrati sui Binding.

L’argomento non era di certo facile ma l’impegno da parte di tutti è stato notevole. Era bello vedere come chi aveva concluso tra i primi poi spiegava o aiutava agli altri, questo è lavoro di squadra!

photo_2017-11-30_23-03-04

Alla prossima settimana!

 

UWP Prism Unit Test

I’m sure we all hear about unit testing, test driven development and so on. These practices are useful and provide a long list of benefit like writing low-coupled and mantainable code to name a few.

We want to write unit test for our UWP Prism application and we’d like, for example, to put our ViewModels under tests to make sure the logic they implement is correct. Unit testing is possible only if we can get rid of all the dependencies in our class under test because we want to run our test every time we want (for exemple when the service library our teammate is writing is not yet finished) and as fast as we can.

Continue reading UWP Prism Unit Test

Prism UWP for beginners: navigation

In this post we’ll talk about the navigation with Prism in UWP. With navigation I mean the technique to go from one page to another of your app. The operation in UWP/XAML is tipically performed with the Frame class that’s available only in the code-behind of a Page because it inherits from Frame. This way we do not respect the MVVM pattern. Prism comes in our help providing a wrapper to the Frame class accessible from the ViewModel: it’s the NavigationService. This isn’t a very new name to us because we found it in the bootstrapper.

protected override Task OnInitializeAsync(IActivatedEventArgs args)
{
//...
Container.RegisterInstance(NavigationService);
//...
}

We saw it at the end of the bootstrap procedure in the OnLaunchApplicationAsync method, too.

protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
NavigationService.Navigate(PageNames.Main.ToString(), null);
return Task.FromResult(true); //This is a little trick because this method returns a Task.
}

To try the navigation system we create a SettingsPage in the View folder and then we’ll navigate to that page with a button in the MainPage.

Immagine

To go to there we need a command in the MainPageViewModel class and bind it in the MainPage view.

public class MainPageViewModel : ViewModelBase
{
public DelegateCommand GoToSettings { get; private set; }

//...
}

In the constructor we initialize the GoToSettings property.

public MainPageViewModel(ITwitterService twitterService, IWeatherService weatherService, INavigationService navigationService)
{

_navigationService = navigationService;

GoToSettings = new DelegateCommand(() =>
{
_navigationService.Navigate("Settings", null);
});
}

In the constructor we added a parameter: the INavigationService reference. This new dependency will be handled by Unity container when resolving an instance of MainPageViewModel. The GoToSettingsCommand is composed by a single line of code where we call the Navigate method with the first argument that is the name of the page where we want to go and the second argument is to add additional information: since we have no additional data we write null.

In this example the Settings page allows us to change the backgorund image of the main page. We notice that in the upper left corner of the application a back. This is handeld by the UWP framwork when detects a navigation.

This back button can be different based on the device where the app is running: phone, tablet or pc. For example in a tablet with tablet mode enabled it will appear on the navigation bar at the botton of the device. In the MSDN we can find al the details.

Screenshot_2.png

When we click the back button we go back to the main page.

When navigating in our view-model we can use two methods to detect when we land into a page or when we leave a page. OnNavigatedTo is callaed when navigation in performed to a page. OnNavigatingFrom is called when navigating away from the page.

   public override void OnNavigatedTo(NavigatedToEventArgs e, Dictionary viewModelState)
        {
            base.OnNavigatedTo(e, viewModelState);

//Loading state custom logic.
        }

        public override void OnNavigatingFrom(NavigatingFromEventArgs e, Dictionary viewModelState, bool suspending)
        {
            base.OnNavigatingFrom(e, viewModelState, suspending);
//Save state logic.
        }

TL;DR

In this post we explored the basic concept about navigating with Prism in UWP App with the Navigation Service and the events that Prism offers to detect the transition from one page to another.

If you want to learn more you can refer to the Prism official website and MSDN. Happy coding!

Prism UWP posts

Prism UWP for beginners: binding and commands

We setup the foundation of a Prism UWP app in the last post. Now we explore binding and commands.

Binding

Binding is the mechanism that connects the UI to the view-model properties to display data in the page and to receive input from the user (with two way binding). We can do binding by implementing the INotifyPropertyChanged interface in our view-model so the view is notified when a property in the view-model changes.

Prism helps us by providing classes that we can use to avoid reinventing the wheel and to start quickly with binding: VisualStateAwarePage and ViewModel.

We use VisualStateAwarePage instead of Page when we create a new view, for example:

<mvvm:SessionStateAwarePage
x:Class="IC6.Buongiorno.Views.MainPage"
mvvm:ViewModelLocator.AutoWireViewModel="True"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:IC6.Buongiorno.Views"
xmlns:mvvm="using:Prism.Windows.Mvvm" >
    <mvvm:SessionStateAwarePage.Background>
        <ImageBrush Stretch="Fill"
            ImageSource="ms-appx:///Assets/wallpaper.jpg" />
    </mvvm:SessionStateAwarePage.Background>

    <Grid Margin="50">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="10*" />
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0"  Margin="10">
            <Button Command="{Binding Update}" Foreground="White">Update
            </Button>
            <TextBlock Text="{Binding Timeline}" Foreground="White" TextWrapping="Wrap" />
        </StackPanel>
        <StackPanel Grid.Column="1"                     HorizontalAlignment="Right">
            <TextBlock Text="{Binding WeatherDescription}" FontSize="32" Foreground="White" />
            <TextBlock Text="{Binding WeatherTemperature}" FontSize="50" Foreground="White" />
        </StackPanel>
    </Grid>
</mvvm:SessionStateAwarePage>

We must replace the Page type in the code-behind, too.

using Prism.Windows.Mvvm;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace IC6.Buongiorno.Views
{
    ///
<summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>

    public sealed partial class MainPage : SessionStateAwarePage
    {
        public MainPage()
        {
            InitializeComponent();

        }

    }
}

We create a MainPageViewModel class in the ViewModels directory and inherit from ViewModel. ViewModel is class of Prism that provides several helpers. In this example we create 3 properties in the ViewModel: Timeline, WeatherDescription, WeatherTemperature. Timeline will expose our Twitter timeline to the UI, WeatherDescrption will expose a brief textual description of the current weather (like “sunny”, “heavy rain”) and WeatherTemperature will expose the current temperature. This is the full MainPageViewModel.

using IC6.Buongiorno.Services.Twitter;
using IC6.Buongiorno.Services.Weather;
using Prism.Commands;
using Prism.Windows.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IC6.Buongiorno.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        ///<summary>
        /// Gets the command to Update Timeline and weather data.
        /// </summary>

        public DelegateCommand Update { get; private set; }

        ///<summary>
        /// Gets or sets the Twitter timeline.
        /// </summary>

        public string Timeline
        {
            get { return _timeline; }
            set { SetProperty(ref _timeline, value); }
        }

        ///<summary>
        /// Gets or sets the current weather description.
        /// </summary>

        public string WeatherDescription
        {
            get { return _weatherDescription; }
            set { SetProperty(ref _weatherDescription, value); }
        }

        ///<summary>
        /// Gets or sets the current weather temperature.s
        /// </summary>

        public string WeatherTemperature
        {
            get { return _weatherTemperature; }
            set { SetProperty(ref _weatherTemperature, value); }
        }

        ///<summary>
        /// Constructor with services.
        /// </summary>

        /// <param name="twitterService">The <see cref="ITwitterService"/> to access Twitter data.</param>
        /// <param name="weatherService">The <see cref="IWeatherService"/> to get current weather information.</param>
        public MainPageViewModel(ITwitterService twitterService, IWeatherService weatherService)
        {
            if (twitterService is null)
            {
                throw new ArgumentNullException(nameof(twitterService));
            }

            if (weatherService is null)
            {
                throw new ArgumentNullException(nameof(weatherService));
            }

            _twitterService = twitterService;

            _weatherService = weatherService;

            Update = new DelegateCommand(async () =>
            {
                Timeline = (await _twitterService.GetTimelineAsync()).Timeline;

                var weatherInfo = (await _weatherService.GetWeather());

                WeatherDescription = weatherInfo.Description;

                WeatherTemperature = $"{weatherInfo.Temperature} °C";
            });
        }

        private string _weatherTemperature;

        private string _weatherDescription;

        private readonly ITwitterService _twitterService;

        private readonly IWeatherService _weatherService;

        private string _timeline;
    }
}

In the code above the SetProperty method is provided by the ViewModel base class and with this we leverage the INotifyPropertyChanged interface to inform the UI that a property has updated its value.

In the constructor we have two dependencies: ITwitterService and IWeatherService. They are handled by the Unity container that we configured in the previuos post. When we’ll ask Unity to resolve an instance of MainPage it will automatically resolve ITwitterService and IWeatherService avoing to us all the heavylifting. This way our code remain clean and easier to read and mantain.

The view-model is automatically linked to the view by Prism beacuse in the page we declared mvvm:ViewModelLocator.AutoWireViewModel="True".

Commands

Commands are the mechanism to support the user interaction without using event handlers. In the Prism framework we find the DelegateCommand that implements the ICommand interface required by XAML.

The ICommand interface exposes a method called CanExecute that is very powerful. With a boolean condition we check if the command is enabled or not. In the MainPageViewModel class we declare an ICommand property and in the constructor we assign a DelegateCommand. In this example we’re getting the timeline from the Twitter service and the weather data from the weather service and assingn to the properties.

In the XAML code above we bind the button Update to this command with the standard binding syntax in the Command property of the Button.

TL;DR

In this post we explored the concepts of bindings and the commands to handle user input and display data retrieved with our services.

Cattura.PNG

Stay tuned for other Prims UWP posts.

Prism UWP posts

Prism UWP for beginners: setup

I want to learn Prism because it may be helpful in some future projects. To better understand how it works I need a target. I’d like to create a simple UWP app that displays my Twitter timeline and the local weather based on the GPS. Prism will help me to adopt the MVVM architeture and IoC/DI concepts. The MVVM and IoC/DI topics are out of the scope of this post.

Setup

I started a new UWP project with Visual Studio 2017 and then imported the Prism.Windows and Prims.Unity NuGet packages. Prism.Windows is the “core” library for the UWP techology and Prism.Unity is the IoC/DI container.

Screenshot_1.png

Conversion to Prism

I converted the Universal app to a Prism Universal app by configuring the bootstrapper. The bootstrapper is a required procedure by the Prism framework to properly initialize all the infrastructure. In vanilla UWP, the bootstrapper is the App class. I edited the App class so that it doesn’t inherit from the native Application class but from a Prism class called PrismUnityApplication.

This is the full App.xaml file.

<prismUnity:PrismUnityApplication x:Class="IC6.Buongiorno.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prismUnity="using:Prism.Unity.Windows"
RequestedTheme="Light">

</prismUnity:PrismUnityApplication>

 

This is the full App.xaml.cs file.

using System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Prism.Unity.Windows;
using Prism.Windows.AppModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Resources;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using IC6.Buongiorno.Services.Twitter;
using IC6.Buongiorno.Services.Weather;

namespace IC6.Buongiorno
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public sealed partial class App : PrismUnityApplication
{

public App()
{
InitializeComponent();
}

protected override UIElement CreateShell(Frame rootFrame)
{
var shell = Container.Resolve<Shell>();
shell.SetContentFrame(rootFrame);
return shell;
}

/// <summary>
/// Logic of app initialization.
/// This is the best place to register the services in Unity container.
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
protected override Task OnInitializeAsync(IActivatedEventArgs args)
{
System.Diagnostics.Debug.WriteLine(">>>>>>>>>>>>> OnInitializeAsync called.");

Container.RegisterInstance<ITwitterService>(new TwitterService());

Container.RegisterInstance<IWeatherService>(new WeatherService());

Container.RegisterInstance<IResourceLoader>(new ResourceLoaderAdapter(new ResourceLoader()));

Container.RegisterInstance(SessionStateService);

Container.RegisterInstance(NavigationService);

return base.OnInitializeAsync(args);
}

protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
NavigationService.Navigate(PageNames.Main.ToString(), null);

return Task.FromResult(true); //This is a little trick because this method returns a Task.
}
}
}

 

I created a Paged called Shell. The Prism definition of shell is:

The main window of an application where the primary UI content is contained.

Shell is called in the CreateShell method triggered by the Unity framework to create the main window of the application.

The OnInitializeAsync method is the place to initialize the Unity container. Here I registered my services. With registering I mean telling Unity that, for example, every time I need an ITwitterService it has to give me an instance of TwitterService. I also register the NavigationService and SessionStateService that I’ll explain in other posts.

I created the standard MVVM folders because Prism is convention based for some of its features.

image

I deleted the default MainPage.xaml file and created a new one in the Views directory as shown in the image above.

Inside OnLaunchApplicationAsync I called the NavigationService.Navigate method to navigate to the MainPage which accepts as first parameter the name of the page (the name of the View without the Page suffix): by passing as parameter the value “Main” Prism searches, in the Views folder, a page called MainPage.xaml. The second parameter is null because I didn’t have additional parameters to pass. The last statement is a little trick because this method returns a Task and I created a fake one with a constant true value.

TL;DR

I made my first steps with Prism in a UWP application: I created the shell and setup the bootstrapper.

Prism UWP posts

 

 

How to get started with Prism in 3 easy steps

In this post we explore the basics of Prism to create a mantainable and scalable WPF application.

IC368873.png

How to get started

  1. Download the nuget Prims.Xyz package for your Platform: in this example for WPF (Prims.WPF and Prism.Unity) with Visual Studio;
  2. Create a bootstrapper;
  3. Edit App.xaml and App.xaml.cs files;
  4. (Bonus point) Reorganize our project.

With this procedure we are setting the foundation for our Prism-enabled app.

1. Download

With the Manage Nuget tool in Visual Studio download the following packages: Prims.WPF and Prims.Unity. Visual Studio will take care of the process and at the end we’ll have these packages installed:

s1.png

2. Create a Bootstrapper

In our project we add a new Class. The name is not important but it has to derive from UnityBootstrapper.

using Microsoft.Practices.Unity;
using Prism.Unity;
using System.Windows;

namespace IC6.Prism
{
 class Bootstrapper : UnityBootstrapper
 {
   protected override DependencyObject CreateShell()
   {
    return Container.Resolve<MainWindow>();
   }

 protected override void InitializeShell()
   {
    Application.Current.MainWindow.Show();
   }
 }
}

3. Edit App.xaml and App.xaml.cs files.

In our project we edit the App.xaml to remove the StartupUri attribute since now that part of the initialization is handled by Prism with Unity.

<Application x:Class="IC6.Prism.App"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:IC6.Prism">
 </Application.Resources>

 </Application.Resources>
</Application>

In the code behind file (App.xaml.cs) we override the OnStartup method to implement our custom startup logic that leverages the Bootstrapper.

using System.Windows;

namespace IC6.Prism
{
 public partial class App : Application
 {
   protected override void OnStartup(StartupEventArgs e)
   {
    base.OnStartup(e);

    var bootstrapper = new Bootstrapper();
    bootstrapper.Run();
   }
 }
}

4. Bonus point

Since we’re using Prism to get the most from MVVM pattern (and other features) we are going also to better organize our project. We delete the MainWindow.xaml and its code behind files from the solution, then we create a new folder called Views and finally create a new Window called MainWindow inside. This is the result.

s2.png

Back to school time

We’ve started this post with just code and not so much theory about what we are doing.

Why do we need a bootstrapper? A Prism application requires registration and configuration during the application startup process. This is known as bootstrapping the application. The Prism bootstrapping process includes creating and configuring a module catalog, creating a dependency injection container such as Unity, configuring default region adapter for UI composition, creating and initializing the shell view, and initializing modules.

In a traditional Windows Presentation Foundation (WPF) application, a startup Uniform Resource Identifier (URI) is specified in the App.xaml file that launches the main window.
In an application created with the Prism Library, it is the bootstrapper’s responsibility to create the shell or the main window. This is because the shell relies on services, such as the Region Manager, that need to be registered before the shell can be displayed.

Dependency Injection

Applications built with the Prism Library rely on dependency injection provided by a container. The library provides assemblies that work with Unity and it allows us to use other dependency injection containers. Part of the bootstrapping process is to configure. this container and register types with the container.

TL;DR

In this post we introduced Prims and made baby steps. With this approach we’re setting the architecure of our app to be scalable and mantainable. In the next posts we’ll go forward and learn other Prism foundamentals.

Readings

Dependency Injection: https://en.wikipedia.org/wiki/Dependency_injection

Prism GitHub homepage: https://github.com/PrismLibrary/Prism