Apr 18 / Igor Damiani

Windows Store Api su GitHub

Lo scorso mese di marzo Microsoft ha reso disponibili delle API tramite le quali noi sviluppatori possiamo accedere alle informazioni conservate all’interno dei nostri account Dev Center. Le informazioni sono visibili su questa pagina del blog ufficiale di Microsoft. Con la versione attuale di queste API possiamo quindi facilmente avere accesso a:

  • App Acquisitions (i download)
  • IAP Acquisistions (gli acquisti in-app effettuati dagli utenti all’interno delle nostre app)
  • Ratings (il numero di stelline)
  • Reviews (le recensioni scritte manualmente dagli utenti)
  • App Health (ovver le app failure, le eccezioni scatenate all’interno delle nostre app)

A patto di litigare con Active Directory di Azure ed impostare il nostro Dev Center di conseguenza (guardate il link di prima per tutti i dettagli del caso), e successivamente di reperire Tenant Id, Client Id e Client Secret, possiamo effettuare chiamate http per ottenere oggetti JSON da deserializzare. Possiamo ordinare, applicare filtrare in base al tempo, etc. etc. Ed otteniamo alla fine oggetti che contengono tutte le informazioni che abbiamo richiesto in base alla API invocata.

Se si può servire, sappiate questo: come Brain-Sys abbiamo pubblicato un progetto su GitHub dedicato a questo tema. Il progetto contiene un po’ di codice open-source che dovrebbe semplificarvi un po’ il lavoro. In pratica non occorre più lavorare a basso livello con HttpClient, autenticarsi ed effettuare chiamate via http, ma c’è una libreria di classi (partendo dalla WindowsStoreApiConnector che è il cuore di tutto) molto più semplice ed efficace da utilizzare.

Oltre a tutto questo, da questa mattina trovate anche un bel pacchetto su NuGet pronto per essere utilizzato. E’ una libreria portable, per cui è utilizzabile da console, WPF, qualsiasi applicazione ASP.NET MVC, etc. etc.

Feedback sono ben accetti!

Send to Kindle
Apr 14 / Igor Damiani

27 Maggio: Focus Day On Developer Tools

Sono felice di annunciare che il prossimo 27 maggio (è un venerdì!) si terrà una bella giornata battezzata Focus Day On Developer Tools, organizzata da Overnet Education. Insieme a Gabriele Gaggi, Alessandro Del Sole e Mauro Servienti vi racconteremo un po’ di cose nell’orbita degli strumenti di sviluppo Microsoft, a partire ovviamente dal nostro amato Visual Studio 2015.

image

Vi racconteremo di Git & GitHub, delle grossissime novità per quanto riguarda Xamarin Forms, di tutti i nuovi strumenti dedicati ai Developer Web. Io personalmente avrò il piacere di parlarvi dello sviluppo di applicazioni con la tecnologia Universal Windows Platform, quindi del mondo Windows 10, soprattutto delle novità che sono state rese pubbliche durante l’ultima Build. Ma non solo quello.

Sulla pagina Facebook dedicata dell’evento potete dare un’occhiata all’agenda, così come anche sulla pagina ufficiale sul sito Overnet: http://overneteducation.it/DettaglioCorso.aspx?corso=EV039&v=1.

Iscrivetevi, il costo di partecipazione è davvero alla portata di tutti!!

Ci vediamo là!!!!!

Send to Kindle
Mar 8 / Igor Damiani

Azure Service Bus Relay, ovvero come esporre un WCF on-premise sul cloud

L’Azure Service Bus Relay (d’ora in poi ASBR) è il servizio messo a disposizione da Azure che ho scoperto più di recente, grazie al mio capo Gabriele Gaggi che me ne ha parlato chiedendomi di studiarlo & provarlo, perchè ci sarebbe stato molto utile in uno scenario che dobbiamo risolvere. Effettivamente l’ASBR è molto molto interessante, e risolve un compito piuttosto ostico, con estrema eleganza e soprattutto relativamente poco lavoro per noi sviluppatori.

A che serve? Semplificando di molto, l’ASBR permette di esporre un servizio Windows Communication Foundation (WCF), che gira on-premise in una rete LAN aziendale, direttamente sul cloud pubblico. Senza bisogno di impazzire con l’apertura di porte sul firewall, di stabilire regole di routing, o più in generale di andare ad apportare cambiamenti pericolosi nell’infrastruttura di rete aziendale.

La tipica domanda che mi viene posta è la seguente: ma se ti serve un WCF sul cloud, perchè non ne fai direttamente il deploy su Azure? Se mi fate questa domanda è perchè siete troppo web-oriented-only, e questo è decisamente male. Spesso e volentieri sono costretto ad avere un servizio WCF che gira on-premise, per diverse ragioni: per motivi di policy, e soprattutto perchè il più delle volte questo servizio deve dialogare con una periferica via USB. Di conseguenza, sono obbligato ad avere un PC server che comunica con la periferica tramite WCF (hostato in un Windows Service, per esempio), che assolve a tutta una serie di compiti (logging, monitoraggio e controllo della periferica, reportistica, etc. etc.); nel mondo moderno, però, il web non è da trascurare, e quindi questo WCF deve anche essere reso disponibile sul cloud.
ASBR serve proprio a questo, con il minor sforzo possibile.

Il tutto è contenuto in questo articolo, che ho seguito passo-passo per ottenere il risultato finale.

1) Creare un service bus su Azure
Il primo step da completare è quello di creare un service bus su Azure. Nel momento in cui vi scrivo, questa operazione non è ancora possibile con l’Azure Portal nuovo, ma dovete accedere a quello classico, disponibile all’indirizzo https://manage.windowsazure.com.

image

Nel mio caso ne ho creato uno chiamato exposedwcf. Da questo servizio bus dovete recuperare il nome (che in realtà avete scelto voi) e la primary key (chiave primaria).

2) Creare il server WCF
Ovviamente, dovete innanzitutto avere un servizio WCF che gira sul PC, allo scopo di pubblicarlo sul cloud. Come esempio, potete vedere quello che ho pubblicato sul GitHub di Brain-Sys all’indirizzo https://github.com/Brain-Sys/ASBR_Server.

Si tratta di un banale WCF hostato in una Console Application.
Il servizio WCF prevede la seguente interfaccia:

namespace ASBR_Server
{
using System.ServiceModel;

[ServiceContract(Namespace = "urn:ps")]
interface IProblemSolver
{
[OperationContract]
int AddNumbers(int a, int b);
}

interface IProblemSolverChannel :
IProblemSolver, IClientChannel { }
}

L’interfaccia è IProblemSolver, ed espone un unico metodo AddNumbers che, con molta fantasia, prende due integer e restituisce la loro somma. L’implementazione è estremamente banale.

static void Main(string[] args)
{
var sh = new ServiceHost(typeof(ProblemSolver));
sh.Open();
Console.WriteLine("Server started!!!");
Console.WriteLine("Press ENTER to close");
Console.ReadLine();
sh.Close();
}

Viene create un’istanza di ServiceHost, al quale viene passata in input l’interfaccia del servizio. Poi il servizio parte, con il classico Console.ReadLine() per fare in modo che il servizio rimanga in attesa (ovviamente questo vale per una Console Application).

Da notare che nel file app.config il servizio WCF ha due endpoint. Il primo è associato ad un binding di tipo netTcpBinding, il cui url è net.tcp://localhost:9358/solver, ed è l’indirizzo che viene esposto ovviamente all’interno della LAN sulla rete on-premise. Il secondo endpoint invece utilizza un binding di tipo netTcpRelayBinding, il cui url è sb://exposedwcf.servicebus.windows.net/solver. Notare il protocollo sb://, che indica appunto l’utilizzo del service bus su Azure. Questo è l’url al quale dovranno puntare i client che raggiungeranno il servizio da remoto, e quindi al di fuori della rete aziendale, accedendoci da Azure.

Fate riferimento al repository GitHub indicato prima per tutti i dettagli del caso.

3) Creare il client WCF

L’altra faccia della medaglia è il client. Anch’esso è una banale applicazione di tipo Console.

Fate riferimento al repository https://github.com/Brain-Sys/ASBR_Client su GitHub.

In questo progetto abbiamo ripetuto la definizione dell’interfaccia IProblemSolver vista prima. Il file Program.cs fa una cosa molto molto banale.

static void Main(string[] args)
{
Random rnd = new Random((int)DateTime.Now.Ticks);
var cf = new ChannelFactory<IProblemSolverChannel>("solver");
var ch = cf.CreateChannel();

for (int i = 0; i < 1000; i++)
{
int a = rnd.Next(1, 100);
int b = rnd.Next(1, 100);
Console.WriteLine("Richiesta " + (i + 1));
Console.WriteLine(ch.AddNumbers(a, b));
}

Console.ReadKey();
}

Viene aperto un canale di comunicazione verso il servizio WCF (notare che la configurazione del servizio WCF è contenuta nel file App.config, che qui non si vede). Poi viene invocato per 1.000 volte il metodo AddNumbers(a, b), chiedendo al servizio WCF di risolvere la somma e di restituirci il risultato.

Et voilà, il gioco è fatto! Il client si connette al servizio WCF via Azure. Questo significa che a costo zero (ovvero: senza toccare nulla del nostro codice), possiamo prendere un servizio WCF già pronto ed esporlo sul cloud, semplicemente aggiungendo un nuovo endpoint tramite l’ASBR.

Anche in questo caso, date un’occhiata al repository GitHub ASBR_Client indicato prima.

4) Conclusione

E’ semplice fare una prova del nove. Lanciate il servizio WCF server sul vostro PC, che si metterà in attesa di un qualche client che si connetta. Compilate il client, passatelo ad un collega o a qualcuno che sta dall’altra parte del mondo, o comunque qualcuno al di fuori della vostra LAN, e chiedetegli di lanciare il client. Il suo client raggiungerà il servizio WCF via Azure: il suo client effettuerà 1.000 richieste di AddNumbers(), che verranno risolte dal WCF che gira sul vostro PC. La stessa cosa la potete anche fare voi in locale (server & client sullo stesso PC, per capirci), ma ovviamente non avete la percezione che il WCF sia effettivamente esposto sul Web.

Ulteriori informazioni sull’Azure Service Bus sono raggiungibili qui.

Send to Kindle
Feb 15 / Igor Damiani

Cordova o Xamarin? Su TecHeroes una possibile risposta!

Cordova e Xamarin sono due framework che permettono la realizzazione di app mobile cross-platform. In altre parole, si tratta di strumenti che permettono ad uno sviluppatore di scrivere un’app in grado di girare successivamente sui dispositivi dei mondi Android, iOS e Windows. Più facile a scriversi che a farsi, ovviamente. Quale scegliere delle due? Quali fattori chiave dobbiamo prendere in considerazione per puntare verso l’uno piuttosto che sull’altro? Produttività? Costi? Competenze? Ambienti di sviluppo?

image

Provate a seguire questa puntata della serie TecHeroes di Microsoft Italia intitolata “Sviluppo cross-platform: Cordova vs Xamarin”, pubblicata sul canale ufficiale Channel 9 lo scorso 2 Febbraio. Il mio boss Gabriele Gaggi, insieme a Matteo Pagani ed Erica Barone di Microsoft vi intratteniranno per poco più di 30 minuti parlando proprio di Cordova e Xamarin. Purtroppo impegni di lavoro e trasferte qua e là mi hanno un po’ impedito la tempestiva segnalazione qua sul mio blog, ma meglio tardi che mai.

Buona visione!!!!

Send to Kindle
Gen 18 / Igor Damiani

Controlli UWP e DeferLoadStrategy

Questa sera qui sul mio blog linko semplicemente questo articolo che parla di Universal Windows Platform, dei suoi controlli e della possibilità di ritardare il loro caricamento tramite la proprietà DeferLoadStrategy. Quest’ultima sostanzialmente si occupa di evitare di caricare il visual tree di tutti quei panel (ma in generale è un ragionamento che si applica a tutti i controlli UWP) che soddisfano due condizioni:

  • DeferLoadStrategy = “Lazy”
  • Visibility = “Collapsed”

Davvero comodo in ottica UWP, dove sappiamo benissimo che le view devono adattarsi a diverse piattaforme e scenari. Giocando con queste nuove proprietà è possibile ottimizzare il parsing ed il caricamento dello XAML facendo in modo che il visual tree contenga solo i controlli UI previsti.

Me lo ero appuntato su Twitter, ma riportato qui sul mio blog mi risulta più comodo!

Buona lettura & Buon sviluppo!!!

Send to Kindle
Gen 7 / Igor Damiani

Steam Controller, recensione personale

A Natale ho ricevuto un bel regalo geek da parte della mia ragazza che – conoscendomi ormai bene – sa quanto io ami svagarmi dal lavoro con qualche videogioco acquistato su Steam. Non ho mai avuto una console in vita mia, e per me giocare significa farlo prevalentemente con il PC. Già negli anni scorsi ho parlato di Steam, per cui se siete miei fedeli lettori sapete quanto io adori questa piattaforma di distribuzione di Valve (gli ideatori della serie di Half Life, per capirci).

Beh, insomma, la mia ragazza mi ha regalato lo Steam Controller.
Ed è stata una incredibile sorpresa.

Che cos’è? A cosa serve?
Sullo Store di Steam lo Steam Controller c’era da molto tempo e mi faceva venire l’acquolina in bocca, ma alla fine ho sempre rimandato l’acquisto (per risparmiare, per pigrizia, per un leggero dubbio che comunque imperversava nella mente). Ed ho sempre sbagliato, perchè funziona un gran bene con tantissimi videogiochi. Ma andiamo con calma.

Che cos’è lo Steam Controller? E’ banalmente un controller per PC, che funziona in modalità wired o wireless: il modello è unico, per cui non dovete scegliere uno o l’altro. Semplicemente acquistate lo Steam Controller e poi scegliete come usarlo. Nella scatola trovate il seguente materiale:

  • il controller, ovviamente
  • il dongle USB da inserire nel PC (foto qui sotto)

  • un cavetto USB –> Micro USB che ha due scopi: o usare il controller in modalità wired, oppure per collegare la base su cui poi collegare il dongle di cui sopra. Quest’ultima soluzione serve nel momento in cui non riusciate (o non vogliate) collegare direttamente il dongle al PC, per motivi di spazio o per entrare nel raggio dei 5 metri di portata

  • batterie, due foglietti di istruzioni, etc. etc.

L’utilizzo è molto semplice. Si inserisce il dongle al PC e si avvia Steam. Steam rileva immediatamente il nuovo controller. Non c’è bisogno di installare alcun driver o software.

Qui ci sono due cose da dire importanti: Windows non rileva il controller come un normalissimo controller da gioco; morale: potete utilizzare lo Steam Controller solo all’interno di giochi comprati e/o configurati all’interno di Steam. Poco male. Secondo: il controller funziona solo ed esclusivamente quando si entra nella modalità Big Picture. Può sembrare uno svantaggio, ma dopo un paio di giorni ho cambiato idea. Ne parlo fra poco.

A chi è rivolto? Serve a tutti?
Procediamo con calma. Ho appena detto che lo Steam Controller è utilizzabile solo ed esclusivamente nella modalità Big Picture. Di cosa si tratta? E’ una modalità che trasforma Steam dalla classica applicazione desktop per Windows ad una modalità entertainment da console, stile XBox o Playstation, per capirci. Steam gira in pieno schermo, ed è possibile navigare all’interno di tutte le funzioni Steam usando tastiera, mouse oppure lo Steam Controller. Qualche foto rende meglio l’idea.

Non direste che si tratta di un PC, vero? Andiamo oltre. Personalmente ho sempre snobbato la modalità Big Picture, invece in questi pochi giorni di relax mi sono dovuto ricredere. Al contrario di quanto accade con la tradizionale modalità desktop, la Big Picture è decisamente più accattivante. Con lo Steam Controller è possibile navigare tutte le sezioni di Steam: la libreria, lo store, la community, le recensioni dei giochi, il workshop, etc. E’ possibile entrare nelle impostazioni di Steam, impostare il controller in modo specifico per ciascun gioco installato (mappando tasti, sensibilità delle levette), e via dicendo.

Sotto tantissimi aspetti, ritengo che la modalità Big Picture di Steam sia molto più curata rispetto alla versione desktop che ho sempre utilizzato. E’ difficile spiegare il motivo così a parole. La versione desktop, per esempio, per esempio, presenta quattro sezioni distinte fra loro: Negozio, Libreria, Comunità ed un’ultima sezione dedicata al nostro account. Quando si entra in una sezione, le altre rimangono escluse. Nella modalità Big Picture, invece, si ha tutto a portata di mano. Esempio: per poter giocare, è necessario entrare nella pagina dedicata al gioco che ci interessa (funzione che non esiste nella modalità desktop), e da qui è possibile raggiungere i contenuti associati al gioco stesso: ultime news, recensioni, screenshot e video degli altri utenti. Il tutto a pochi clic di distanza, con lo Steam Controller o con il mouse.

Lo Steam Controller è adatto a tutti? Direi di sì, anche se rende il suo meglio quando si riesce a collegare il PC ad una televisione come faccio io. Perchè? Perchè Big Picture rende l’esperienza d’uso molto più immersiva e più adatto ad un uso da salotto. Non c’è nulla di male ad usare lo Steam Controller con un classico monitor da PC, sia chiaro, ma secondo me dà il suo meglio con una bella TV come sto facendo io.

Ok, parliamo del controller, adesso!
E’ giunto il momento di parlare del controller vero e proprio. Chiunque l’abbia pensato, ha fatto davvero un ottimo lavoro. Giocando con il PC, la combinazione migliore è sicuramente quella composta da tastiera + mouse, praticamente obbligatoria quando si gioca a sparatutto come CoD, Wolfstein, etc. etc. Con il mouse vi guardate attorno (mano destra), mentre con la tastiera camminate (tasti WASD) ed inviate comandi al vostro avatar (mano sinistra).

Lo Steam Controller cerca di portare questa esperienza d’uso all’interno di un controller. Innanzitutto ha tra aree di controllo principali che si comportano in modo diverso:

  1. il classico joystick analogico (quello al centro)
  2. il classico controllo a croce digitale per le quattro direzioni (quello più a sinistra). Bellissimo perchè funziona anche solo sfiorando la superficie del trackpad; in realtà supporta anche il click, ma onestamente non mi è ancora chiaro se si tratta di due azioni diverse. E’ comunque molto comodo perchè si può spostare il proprio personaggio evitando di utilizzare troppo (leggesi: sollecitare) il joystick analogico del punto (1)
  3. un innovativo touchpad, molto simile a quello già esistente sui notebook da parecchi anni (quello più a destra)

Quest’ultimo è leggermente concavo, lo si utilizza con il pollice destro, vibra leggermente al tocco per dare un feedback al giocatore, ed emula il comportamento del mouse. Lo utilizzate esattamente come un touchpad da portatile, solo che mentre quest’ultimo lo utilizzate un po’ come volete, quello dello Steam Controller lo utilizzate con il pollice per direzionare lo sguardo del vostro alter-ego all’interno del gioco. Con la mano sinistra vi muovete ed il gioco è fatto.

Chiaramente lo Steam Controller dispone di numerosi altri pulsanti: dai classici X, Y, A e B fino a quelli posti sul retro (tre per mano).

I pulsanti sul retro sono azionabili con indice e dito medio delle due mani, e possono essere configurati a piacimento, in base al gioco. Sul retro c’è anche l’alloggiamento per le due batterie AA necessarie per il funzionamento, che sono comprese nella confezione.

La versatilità del controller è eccezionale, il peso adeguato, e l’integrazione con la community è molto molto utile. Ciascuno di noi può crearsi una configurazione per lo Steam Controller specifica per un gioco, e salvarla sul cloud di Steam, in forma privata o pubblica. Se una configurazione è pubblica, allora è scaricabile ed utilizzabile da altri giocatori. In pratica non c’è più nemmeno lo sbattimento di doversi settare il controller: qualcuno l’ha già fatto probabilmente prima di noi. Spettacolare.

Lo Steam Controller è dotato poi di un pulsante Steam illuminato che serve per entrare in una modalità di editing del gioco corrente, per personalizzare il setup associato al gioco corrente e così via. Emette un suono quando si accende e si spegne. Dallo Steam Controller è possibile controllare anche il sistema operativo:

E’ possibile uscire da Steam, riavviare o spegnere il PC, eccetera. Davvero comodo.

Io lo utilizzo in modalità wireless; il dongle USB dista 3,5 metri dal divano su cui mi trovo, e non ha il minimo problema di ricezione. Ottimo. Il controller è molto ben supportato: in questi pochi giorni ho già ricevuto due aggiornamenti del firmware; ho il sospetto che abbiano diminuito l’intensità della vibrazione che il controller emette quando si utilizza il touchpad di destra.

E’ difficile da utilizzare? La risposta è dipende, è molto soggettiva. Se siete sempre stati abituati ad un controller da console, vi troverete incredibilmente bene. Se avete sempre giocato con il PC, come me, allora la curva di apprendimento/adozione sarà un po’ più ripida. In questi giorni sto passando il tempo con SOMA, un horror fantascientifico, il cui gameplay è prevalentemente basato su enigmi ed esplorazione di basi sottomarine. Zero combattimenti, insomma. E questo mi aiuta per impratichirmi un po’. Vedo molto difficile che andrò ad utilizzarlo con Call Of Duty o altri giochi FPS in soggettiva. Di sicuro va benissimo per giochi di strategia, RTS, RPG come Skyrim, eccetera.

Costo dello Steam Controller
Un ultimo appunto sul costo. Il controller costa 54,99 euro, al quale vanno aggiunte le spese di spedizione. La mia ragazza ha speso 12,30 euro di spedizione, per un totale quindi di 67,29 euro.

Se siete curiosi e volete vedere altre fotografie, consultate l’album fotografico che ho pubblicato su Flickr : https://www.flickr.com/photos/igordamiani/albums/72157663253065485.

Insomma, promosso a pieni voti!!!!

Send to Kindle
Nov 27 / Igor Damiani

UWP, MVVM e ListView con multiselezione

Il problema di oggi è quello di avere un’app UWP (Universal Windows Platform), sviluppata seguendo la tecnica del Modem-View-ViewModel, che mostra una ListView con attivata la multiselezione. Ci sono alcuni passaggi che dobbiamo risolvere.

Innanzitutto, l’oggetto ListView espone la proprietà SelectedItem (singolare) ma non una proprietà SelectedItems. Quindi dobbiamo trovare un modo per bypassare il problema. Io ho risolto scrivendo una classe statica SelectionManager, che espone una proprietà List di tipo IList. Da viewmodel posso fare binding su questa dependency property con una proprietà ObservableCollection. All’interno, questa classe sottoscrivere l’evento SelectionChanged della ListView; ogni volta che l’utente seleziona o deseleziona un ListViewItem la lista viene sincronizzata.

public static class SelectionManager
{
public static IList GetList(DependencyObject obj)
{
return (IList)obj.GetValue(ListProperty);
}

public static void SetList(DependencyObject obj, IList value)
{
obj.SetValue(ListProperty, value);
}

public static readonly DependencyProperty ListProperty =
DependencyProperty.RegisterAttached("List",
typeof(IList),
typeof(SelectionManager),
new PropertyMetadata(null,
new PropertyChangedCallback(SetupList)));

private static void SetupList(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
ListViewBase lst = d as ListViewBase;
lst.SelectionChanged += Lst_SelectionChanged;
}

private static void Lst_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
ListViewBase element = sender as ListViewBase;
var arrayList = GetList(element);

foreach (object o in e.AddedItems)
{
arrayList.Add(o);
}

foreach (object o in e.RemovedItems)
{
if (arrayList.Contains(o))
{
arrayList.Remove(o);
}
}
}
}

A livello di ViewModel espongo due ObservableCollection pubblici: una funge come ItemsSource per la ListView stessa (grazie alla quale la ListView mostra l’elenco degli Items), l’altra invece è una ObservableCollection che mantiene costantemente aggiornato l’elenco degli Items selezionati. Ecco uno stralcio di XAML per rendere evidente questa cosa.

<ListView
ItemsSource="{Binding Cars}"
SelectionMode="Extended"
hlp:SelectionManager.List="{Binding SelectedCars}" />

La proprietà Cars è una ObservableCollection<Car> che fa da datasource alla ListView, come si fa di solito. La proprietà SelectedCars è un’altra ObservableCollection<Car> dedicata solamente al mantenimento degli items correntemente selezionati.

Un altro approccio che NON ho preferito

Un altro approccio che avrei potuto seguire è quello di passare al mio SelectionManager la stessa ObservableCollection impostata su ItemsSource (nel mio caso qui sopra, quindi, Cars). Con questa logica la mia SelectionManager avrebbe potuto impostarmi una proprietà booleana IsSelected su ciascuna delle istanze di Car che risultano selezionate.

Non ho preferito questa strada per due ragioni:

  1. Così facendo sarai stato costretto ad aggiungere una proprietà bool IsSelected sul mio viewmodel, cosa che non sempre vorrei/potrei fare. D’altro canto, invece, SelectionManager è in grado di lavorare con qualsiasi tipo di classe. Quando un oggetto risulta selezionato sulla UI esso viene aggiunto alla lista in binding; quando viene deselezionato l’oggetto viene rimosso
  2. Avendo una proprietà dedicata alla multiselezione, posso fare immediatamente binding sulla mia UI. Nel mio esempio ho una proprietà SelectedCars pronta all’uso ed aggiornata, quindi è semplicissimo aggiungere al visual tree una TextBlock la cui proprietà Text fa binding con un {Binding Path=SelectedCars.Count} (per visualizzare il numero di elementi selezionati). Con questo secondo approccio, invece, avrei un’unica proprietà Cars, e per ottenere l’elenco degli Items selezionati devo continuamente giocare con LINQ e fare una query per ottenere le Cars selezionate

Se serve, posso aggiungere un Command ed un CommandParameter

Una volta sviluppata la classe SelectionManager con il codice qui sopra, è un gioco da ragazzi aggiungere due nuove dependency property: una di tipo ICommand ed una di tipo object. Lo scopo in questo caso è quello potenzialmente di andare ad eseguire un Command sul mio viewmodel dopo che la selezione è stata gestita (se serve, mica è obbligatorio).

Ecco il codice completo della classe SelectionManager:

public static class SelectionManager
{
public static IList GetList(DependencyObject obj)
{
return (IList)obj.GetValue(ListProperty);
}

public static void SetList(DependencyObject obj, IList value)
{
obj.SetValue(ListProperty, value);
}

public static readonly DependencyProperty ListProperty =
DependencyProperty.RegisterAttached("List",
typeof(IList),
typeof(SelectionManager),
new PropertyMetadata(null,
new PropertyChangedCallback(SetupList)));

public static ICommand GetCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(CommandProperty);
}

public static void SetCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(CommandProperty, value);
}

public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command",
typeof(ICommand),
typeof(SelectionManager),
new PropertyMetadata(null,
new PropertyChangedCallback(SetupList)));

public static object GetCommandParameter(DependencyObject obj)
{
return obj.GetValue(CommandParameterProperty);
}

public static void SetCommandParameter(DependencyObject obj,
object value)
{
obj.SetValue(CommandParameterProperty, value);
}

public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached("CommandParameter",
typeof(object),
typeof(SelectionManager),
new PropertyMetadata(null));

private static void SetupList(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
ListViewBase lst = d as ListViewBase;
lst.SelectionChanged += Lst_SelectionChanged;
}

private static void Lst_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
ListViewBase element = sender as ListViewBase;
var arrayList = GetList(element);

foreach (object o in e.AddedItems)
{
arrayList.Add(o);
}

foreach (object o in e.RemovedItems)
{
if (arrayList.Contains(o))
{
arrayList.Remove(o);
}
}

var command = GetCommand(element);

if (command != null)
{
var parameter = element.GetValue(CommandParameterProperty);

if (command.CanExecute(parameter))
{
command.Execute(parameter);
}
}
}
}

Dopo che l’evento SelectionChanged è stato scatenato, la proprietà del viewmodel viene sincronizzata con la selezione corrente. Dopodichè, se c’è un Command in binding viene eseguito, passando anche il suo eventuale parametro object.

 
Fine!
Send to Kindle
Nov 4 / Igor Damiani

Applicazioni UWP: come gestire correttamente il tasto Back

Le applicazioni Universal Windows Platform sono organizzate attraverso pagine (classe Page), esattamente come accadeva nelle precedenti versioni di Windows 8 ed 8.1. Questo significa che l’app parte mostrando una pagina iniziale, poi l’utente naviga e si sposta secondo un flusso che dipende dall’app stessa. L’utente può ovviamente anche tornare indietro fra le pagine, con diverse modalità dipendentemente dal software e dall’hardware che ha a disposizione. Ad esempio:

  • su uno smartphone l’utente può utilizzare il tasto hardware fisico Back, oppure può toccare il tasto software previsto da Windows (come ad esempio su un Lumia 640 LTE)
  • su un tablet o su un PC Windows 10 il tasto hardware Back non esiste, per cui l’utente può solamente cliccare/toccare il tasto Back software previsto dal sistema operativo. Questo tasto si può trovare in due punti distinti: se la modalità Tablet è spenta, allora il pulsante si trova sulla barra del titolo relativo all’app stessa. Se la modalità Tablet è attiva, allora il pulsante si trova sulla taskbar di Windows
  • Da notare che l’utente può posizionare la taskbar su uno dei quattro lati dello schermo, per cui il tasto Back fisicamente può ritrovarsi ai quattro angoli dello schermo:
    – taskbar inferiore : tasto Back nell’angolo in basso a sinistra
    – taskbar sul lato sinistro : tasto Back nell’angolo in alto a sinistra
    – taskbar superiore : tasto Back nell’angolo in alto a sinistra
    – taskbar sul lato destro : tasto Back nell’angolo in alto a destra
  • L’app può ovviamente anche contenere un pulsante Back previsto dallo sviluppatore ed inserito all’interno della pagina: aspetto, posizionamento e comportamento dipendono ovviamente da chi scrive il codice ed implementa la pagina

Qualche screenshot è d’obbligo per chiarire meglio le cose.

image

Sopra : Pulsante Back sulla barra del titolo in un’app UWP con modalità Tablet spenta.

image

Sopra : Pulsante Back sulla taskbar di Windows agganciata al lato sinistro dello schermo, con modalità Tablet attiva.

image

Sopra : Pulsante Back sulla taskbar di Windows agganciata al lato inferiore dello schermo, con modalità Tablet attiva.

Rendere visibile o invisibile il tasto Back 
Vediamo adesso qualche riga di codice C# per gestire tutti questi scenari.

Innanzitutto, occorre controllare la visibilità del pulsante Back, che di default è e rimane nascosto. Con Windows 10 questo pulsante non fa parte della nostra UI, non è un contenuto inserito nelle nostre pagine tramite XAML, per cui se vogliamo controllarlo dobbiamo passare da classi che consentono l’accesso a questo componente messo a disposizione dal sistema operativo. Ad esempio, se vogliamo rendere visibile il pulsante Back ogni volta che si naviga verso una nuova pagina il codice necessario è il seguente:

SystemNavigationManager.GetForCurrentView()
.AppViewBackButtonVisibility =
((Frame)sender).CanGoBack ?
AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;

Dove posizionare questo blocco di codice? Ecco il codice completo che suggerisco:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;

if (rootFrame == null)
{
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
rootFrame.Navigated += RootFrame_Navigated;
Window.Current.Content = rootFrame;
}

if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}

Window.Current.Activate();
}

private void RootFrame_Navigated(object sender,
NavigationEventArgs e)
{
SystemNavigationManager.GetForCurrentView()
.AppViewBackButtonVisibility =
((Frame)sender).CanGoBack ?
AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;
}
Nel metodo OnLaunched() definito nella classe App sottoscrivo l’evento Navigated della classe Frame, che si scatena ogni qualvolta viene completata la navigazione verso una nuova pagina. Il bottone Back, di conseguenza, viene reso visibile se la proprietà CanGoBack del Frame è true.
Questo, però, completa solo metà del problema. Il bottone è visibile, ma se viene cliccato non accade nulla: per portare l’utente sulla pagina precedente dobbiamo scrivere ancora qualche riga di codice C#.

 

Intercettare la pressione del tasto Back e spostarsi alla pagina precedente

Capire quando l’utente clicca o tocca il pulsante Back e reagire di conseguenza è semplice:

public SecondPage()
{
this.InitializeComponent();

SystemNavigationManager.GetForCurrentView()
.BackRequested += SecondPage_BackRequested;
}

private void SecondPage_BackRequested(object sender,
BackRequestedEventArgs e)
{
if (this.Frame.CanGoBack)
{
this.Frame.GoBack();
}

e.Handled = true;
}

Si utilizza la classe SystemNavigationManager, si ottiene un riferimento alla view corrente e si sottoscrive l’evento BackRequested. Nell’event handler si effettua la navigazione alla pagina precedente: un buon modo per evitare eccezioni o problemi da questo punto di vista è verificare se sia possibile controllando la proprietà CanGoBack esposta da Frame.

 
Ed in un mondo MVVM?
Quando si sviluppa un’app con il pattern MVVM, le cose sono un po’ diverse, ma non molto. Non scriviamo codice nel code-behind della Page, bensì abbiamo a che fare con una classe ViewModel. Nel costruttore di ciascuna classe ViewModel sottoscriviamo l’evento BackRequested:
 
public AboutViewModel()
{
SystemNavigationManager.GetForCurrentView()
.BackRequested += (s, e) =>
{
e.Handled = true;
base.GoBack();
};
}
Si può evitare di sottoscrivere l’evento nella classe ViewModel relativa alla prima pagina che parte con l’app, perchè da questa pagina non si può tornare indietro da alcuna parte. Nel momento in cui l’utente clicca/tocca il tasto Back, viene scatenato l’evento BackRequested. Nel mio esempio qui sopra, vado a chiamare il metodo GoBack() esposto da tutti i miei ViewModel, che fa semplicemente:
 
protected void GoBack()
{
Frame rootFrame =
Windows.UI.Xaml.Window.Current.Content as Frame;

if (rootFrame.CanGoBack)
{
rootFrame.GoBack();
}
}
 
In questo modo si evita di andare a lavorare nel code-behind: qui semplicemente si recupera il Frame relativo alla vista corrente e se possibile si scatena la navigazione all’indietro.
 
Et voilà, il gioco è fatto!
Send to Kindle
Ott 31 / Igor Damiani

Installation Guide for Team Foundation Server 2015

Durante il weekend scorso, per prepararmi ad un corso di 3 giorni che avrei dovuto tenere a Trieste su Team Foundation Server ed Application Lifecycle Management, mi sono preparato un pochino e mi sono deciso ad effettuare l’installazione di TFS 2015 all’interno di una macchina virtuale Hyper-V, partendo dal sistema operativo (Windows Server 2012 R2) fino a Microsoft Office 2016, passando da tutte le ultime versioni di software e di strumenti di sviluppo. Non ho molta dimestichezza con le installazioni server, per cui prima di cominciare e tentare ho googlato ed ho trovato questa guida:

Team Foundation Server 2015 (TFS2015) Installation Guide

Include tutto il necessario: Windows Server 2012 R2, SQL Server 2014 Standard Edition, Team Foundation Server 2015, tutte le configurazioni per ogni singolo passo.

E’ una guida davvero ottima, scritta in modo semplice ed illustrata tramite screenshot. Dal mio punto di vista pecca solo di una cosa: non è inclusa l’installazione di Sharepoint Server 2013. Per quest’ultimo setup ho seguito questo link.

Oltre a questo, c’è un ulteriore piccolo problema, che ho provveduto a segnalare anche all’autore del post originario: appena terminata l’installazione di Windows Server 2012 R2, viene detto di attivare Windows Update, che comporta ovviamente il download e l’installazione di tutti gli aggiornamenti di sistema, compresa l’ultima versione del .NET Framework, che al momento è la 4.6. Non ci sarebbe nulla di male, anzi, se non fosse per il fatto che l’installer di Sharepoint Server 2013 non riconosce questa versione di .NET Framework, e quindi non potete più procedere con la sua installazione. Ho provato a disinstallare, a giocare con il registry, ma non ho combinato nulla di buono. Morale: ho dovuto ricominciare daccapo la macchina. Il mio consiglio è quello di lasciare Windows Update spento, fino a quando non avete terminato il setup di tutto quanto, e di attivarlo solo alla fine.

Send to Kindle
Ott 19 / Igor Damiani

Spunti di Adaptive Code con UWP

Quando parliamo di Universal Windows Platform parliamo per diretta conseguenza di Windows 10, e quindi di tutti i possibili hardware capaci di far girare Windows 10, dallo smartphone a tutti gli altri possibili ed immaginabili dispositivi. E’ importante applicare quindi correttamente concetti come Adaptive UI (ovvero un’interfaccia utente capace di adattarsi e di scalare in base alla risoluzione ed allo schermo correnti), ma anche di Adaptive Code, ovvero di codice c# che capisca su quali famiglia di dispositivi ci troviamo e di adattarsi di conseguenza.

Per quale motivo? Ce ne sono tanti, a dir la verità.

Facciamo una cosa semplice. Supponiamo di creare ed istanziare una MessageDialog:

var dialog = new MessageDialog(
string.Format("Aprire il link {0} ?", url),
"Apertura sito Web");
dialog.Commands.Add(
new UICommand { Label = "&Sì", Id = 0 });
dialog.Commands.Add(
new UICommand { Label = "&No", Id = 1 });
dialog.DefaultCommandIndex = 0;
dialog.CancelCommandIndex = 1;
var res = await dialog.ShowAsync();
Notare che ho impostato le label come &Sì e &No, in modo tale che da tastiera sia possibile premere ALT+S e ALT+N per rispettivamente premere Sì oppure no. La tastiera però su smartphone non ce l’abbiamo, quindi questa è una feature che non è supportata. Purtroppo, con la build corrente di Windows 10 for Mobile quelle & commerciali compaiono comunque, con uno sgradevole effetto per l’utente finale. La soluzione è intercettare e capire su quale famiglia di device ci troviamo a run-time, ed adattarci in base allo scenario.
Possiamo capire su quale famiglia di dispositivi Windows 10 ci troviamo con questa linea di codice:
string family = Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily;

Il valore restituito è una semplice stringa. E quindi possiamo scrivere:

string family = Windows.System.Profile
.AnalyticsInfo.VersionInfo.DeviceFamily;
string yesLabel = "Sì";
string noLabel = "No";

if (family == "Windows.Desktop")
{
yesLabel = "&Sì";
noLabel = "&No";
}

Windows.Desktop è il valore che quella DeviceFamily assume quando il codice gira sotto l’ambiente desktop (quindi PC di varia natura). Il valore diventa Windows.Mobile se il codice sta girando sotto smartphone.

Send to Kindle