Win 10 IoT Remote Display

Since the advent of Windows 10 IoT Core, I've always dreamed to see the video output of my Raspberry Pi 2 on my PC screen, as we do with Remote Desktop for VMs and remote servers. Finally, we can do it!

First, you need to follow the steps illustrated on my previous post to install the latest insider preview version of Windows IoT Core for Raspberry Pi 2 (it works also for RP3).

When you have done it, connect your RP to your WiFi router by Ethernet cable and open the web browser to this URL: http://<yourdevicename>:8080 , then go to the "Remote" page and select the "Enable Windows IoT Remote Server".

Once done, go to the Store and download the "Windows IoT Remote Display" app.

Now open your Visual Studio 2015 (don't forget to apply the brand new Update 2), create or open an UWP app and run it on the remote device.

Finally, run the Remote Display, and voilà, the Raspberry Pi 2 video will appear on your PC screen:

NOTE: Actually, I can't use my PC keyboard to write in the TextBox, I can do it only with the USB keyboard physically attached to the Raspberry Pi 2.

Enjoy and have fun!

Primi passi con Visual Studio Online (step 2)

Questo è il secondo post di una miniserie dedicata a chi non ha ancora provato ad usare Visual Studio Online e ha bisogno di una rapida guida per muovere i primi passi.

La serie comprende:

  1. Creare un account su VS Online;
  2. Creare un Team Project su VS Online;
  3. Collegare il vostro Visual Studio (quello che avete sul vostro PC) con VS Online
  4. Creare una nuova solution e collegarla a un Team Project
  5. Invitare uno o più utenti a partecipare a un proprio Team Project
  6. Accettare l'invito ricevuto e iniziare a collaborare ad un Team Project

Nel primo post abbiamo illustrato i punti 1 e 2.

In questo post illustreremo il punto 3, ovvero come Collegare Visual Studio (quello che avete sul vostro PC) con il vostro Visual Studio Online.

Prima però, un po' di teoria di base sul "Code Versioning":

Code Versioning significa mantenere tutta la storia di quel che è stato fatto in un progetto. Ogni creazione, modifica e cancellazione di file (o parti di essi) viene memorizzata e non viene mai persa. Anche dopo aver rimosso dei file dal progetto, ad esempio, è sempre possibile recuperarli perché il sistema di versioning tiene sempre tutta la storia passata e ogni cancellazione è solo logica.

Per meglio comprendere, immaginate di dover registrare l'andamento di una partita di scacchi. Avete diversi modi di farlo:

  • Filmare tutta la partita
  • Fare delle foto o dei disegni della scacchiera, dopo ogni mossa
  • Registrare ogni mossa (mossa 1: pedina D2 in D4, mossa 2: cavallo C8 in B6, …)

E' chiaro che anche se durante la partita vari pezzi vengono "mangiati" (così come alcuni file possono essere cancellati o modificati), avendo tenuto traccia di tutti i cambiamenti effettuati è sempre possibile ripristinare una determinata situazione precedente, perché i "pezzi" non sono stati veramente eliminati, ma solo rimossi dal piano di gioco.

Visual Studio Online offre due modi di gestire il versioning del nostro codice:

  • TFS Version Control
  • Git

Senza entrare nei dettagli, possiamo dire che la differenza principale tra i due sistemi è che:

  • TFS è un sistema centralizzato, dove tutti i dati risiedono in un archivio dati centralizzato che contiene tutta la storia di tutte le variazioni effettuate, e sulla nostra macchina locale possiamo tenere un solo una determinata situazione, che può essere l'ultima o una precedente, esattamente come per il gioco di scacchi la disposizione dei pezzi nella scacchiera dopo una certa mossa (che può essere l'ultima ma volendo anche una qualsiasi precedente).
  • Git invece è un sistema distribuito, dove ogni utente ha nella propria macchina locale tutta la storia del progetto, ovvero tutte le mosse e tutte le diverse disposizioni dei pezzi nella scacchiera di tutto lo svolgimento del gioco.

Ognuno ha i suoi pro e i suoi contro, e in questa guida utilizzeremo TFS (d'altra parte questa scelta l'abbiamo già fatta quando abbiamo creato il mostro Team Project, e se volessimo usare Git dovremmo crearne uno nuovo).

Ripartiamo quindi dalla home page del nostro sito Team Project su Visual Studio Online e facciamo click su "Open in Visual Studio":

e confermiamo l'autorizzazione ad avviare VS (da ora in poi VS sta per Visual Studio, quello montato sul nostro PC, mentre VSO sta per Visual Studio Online):

Su VS nel pannello "Team Explorer" facciamo click su "Configurare i mapping dell'area di lavoro":

In parole povere, dobbiamo dire a VS dove registrare in locale, nel nostro Hard Disk, la copia di tutti i file che compongono il progetto. Ricordate sempre che con TFS, come già detto, in locale troverete sempre una determinata situazione del progetto e non tutta la sua storia, che invece risiede nel cloud, nella vostra istanza di VSO.

Ci viene proposta una destinazione, all'interno della nostra cartella utente (in questo caso l'utente si chiama "Mario"):

E' possibile impostarne una diversa facendo click sui te puntini. Io personalmente preferisco utilizzare una cartella diversa:

Infine facciamo click su "Esegui mapping e lettura". Il mapping collegherà la cartella dell'hard disk al Team Project, la lettura copierà la situazione attuale (riferendoci all'esempio della partita a scacchi, l'attuale disposizione dei pezzi nella scacchiera) nella cartella suddetta.

Osserviamo alcune cose:

  • Nel pannello del Team Explorer siamo nella pagina iniziale e stiamo lavorando col Team Project "QuickTest".
  • Si è aperta una pagina a sinistra, chiamata Esplora controllo codice sorgente, dove possiamo vedere tutto il contenuto del nostro VSO, a partire dalla "Default Collection" che è il contenitore di tutti i nostri team project.
  • La "Default Collection" contiene il nostro Team Project "QuickTest", che essendo selezionato mostra il suo contenuto nella parte destra della finestra.
  • Il percorso locale contiene il path completo della cartella del nostro hard disk nella quale è contenuta la copia locale del Team Project.
  • Nella barra dei comandi della finestra "Esplora controllo codice sorgente" possiamo leggere qual è l'area di lavoro nella quale è stata registrata la mappatura tra Team Project e percorso locale.

L'area di lavoro è un argomento che esula da questa breve guida, ulteriori informazioni possono essere trovate qui.

E questo completa un altro piccolo passo per l'uso di VS con VSO.

Primi passi con Visual Studio Online

Ok, avete appena scaricato la Community Edition di Visual Studio 2013 (o meglio ancora la release candidate di Visual Studio 2015) ma non avete ancora provato ad usare Visual Studio Online?

Questo post è il primo di una miniserie dedicata a chi non ha ancora provato ad usare Visual Studio Online e ha bisogno di una rapida guida per muovere i primi passi.

La serie comprende:

  1. Creare un account su VS Online (in questo post);
  2. Creare un Team Project su VS Online (in questo post);
  3. Collegare il vostro Visual Studio (quello che avete sul vostro PC) con VS Online
  4. Creare una nuova solution e collegarla a un Team Project
  5. Invitare uno o più utenti a partecipare a un proprio Team Project
  6. Accettare l'invito ricevuto e iniziare a collaborare ad un Team Project

In questo post illustreremo i punti 1 e 2.

Per cominciare, basta andare su visualstudio.com e cliccare su "Inizia subito...":

A questo punto vi apparirà la schermata di login:

Tutti i servizi Online di Microsoft (tra i quali Microsoft Azure e Visual Studio Online) richiedono l'uso di un account Microsoft.

Se avete già scaricato Visual Studio o se avete un indirizzo email che finisce per "@outlook.*", "@live.*", "@hotmail.*" e similari, allora siete già un passo avanti perché avete già un account Microsoft e potete utilizzare l' email e la password ad esso associata per fare il login e saltare la creazione dell'account Microsoft.

Se invece avete un altro indirizzo (Gmail, Yahoo, Tiscali, Liberto, ecc.) prima di accedere dovete creare un account Microsoft e potete farlo cliccando direttamente su "Iscriviti ora" (in questo post non vengono descritti i vari passaggi necessari).

In ogni caso, una volta fatto il login come utente Microsoft tramite click al pulsante "Accedi", vi appare un'altra finestra di registrazione, questa volta come utente di Visual Studio Online:

Qui dovete inserire il nome e il cognome (email è quella del vostro account Microsoft), il Paese (Italia) e, cosa assai importante, il vostro dominio di secondo livello. Nell'esempio abbiamo messo mariorossi72, nel vostro caso dovrete scegliere un nome che non sia già stato utilizzato da qualcun altro.

Ora, con crea account, verrà avviata la creazione di una istanza di Visual Studio Online tutta vostra, raggiungibile all'indirizzo https://<vostro_dominio_di_secondo_livello>.visualstudio.com (nell'esempio mariorossi72.visualstudio.com):

Cliccando sul link mariorossi72.visualstudio.com andiamo finalmente al nostro sito Visual Studio Online, ma poiché è la prima volta che ci andiamo, veniamo subito portati alla pagine di creazione del nostro primo Team Project:

Inseriamo il nome del nostro progetto (in questo caso "QuickTest"), scegliamo il tipo di progetto (in questo caso "Team Foundation Version Control") e clicchiamo su "Create project". Dopo qualche istante di attesa, viene mostrata la seguente finestra di congratulazioni, visto che finalmente abbiamo creato il nostro primo Team Project:

Per andare alla pagina principale clicchiamo su uno dei due pulsanti (in questo caso "Go to Board"):

Dove volendo possiamo inserire nel backlog l'elenco delle cose da fare, ma visto che vogliamo andare alla home page del nostro Visual Studio Online, clicchiamo su Home:

Et voilà, il gioco è fatto. :-)

Nel prossimo post ripartiremo da qui per vedere come utilizzare Visual Studio per collegarci al nostro Visual Studio Online.

 

 

Resource Management delle Windows Runtime Apps

Anche se nel sito MSDN non è difficile trovare documentazione dettagliata sui diversi aspetti della gestione delle risorse di una Windows Store App o Windows Phone Store App, ma nello studio di tale materia non ho trovato una visione d'insieme che facilitasse la comprensione di come i vari aspetti siano legati tra di loro nella realizzazione della mia applicazione. Per tale motivo ho pensato che un post riassuntivo potesse essere utile, rimandando di volta in volta ai singoli articoli MSDN per l'approfondimento delle singole parti.

Ogni volta che eseguiamo la build della nostra applicazione, il Resource Management System crea un file PRI (Package Resource Index) che viene incluso nell'app e che consente di stabilire a runtime quali risorse debbano essere utilizzate in un dato momento.

Informazioni più dettagliate, che vi consiglio di leggere dopo aver completato la lettura di questo post, le potete trovare qui: Resource Management System.

Il file PRI contiene tutte le Named Resource collezionate al momento della build. Il file PRI altro non è che un dizionario di named resources e di referenze ai file di risorse contenute nello app package.

La cosa interessante è che le named resource possono avere più valori, a secondo delle qualified variant. A runtime il Resource Manager applicherà un algoritmo di risoluzione che identificherà tra i resource file associati ad una named resource quello da usare in quel momento, attraverso il confronto delle diverse qualified variant disponibili nel file PRI rispetto al ResourceContext di esecuzione dell'app.

Se, ad esempio, abbiamo una Named Resource chiamata MyImage a cui corrispondono due file jpeg, uno con la qualified variant scale-100 e l'altro con qualified variant scale-140, il file utilizzato a runtime dipenderà dalla scale del ResourceContext di esecuzione.

Di seguito l'elenco delle diverse Qualified Variant disponibili:

  • language (può essere abbreviato a "lang" quando viene usato nel nome di file della risorsa, o addirittura omesso se utilizzato nel nome di una cartella)
  • scale
  • contrast
  • homeregion
  • targetsize
  • layoutdir
  • config
  • altform
  • DXFeatureLevel (può essere abbreviato con "DXFL")

Maggiori Informazioni le potete trovare qui: How to name resources using qualifiers (XAML).

Ok, dunque possiamo associare a una Named Resource diversi file risorsa, univocamente identificati da una qualsiasi combinazione delle qualified variant disponibili.

Ma dove dobbiamo mettere tali file nel nostro progetto di Visual Studio, e come dobbiamo chiamarli affinché durante la build questi file vengano riconosciuti come file risorse e vengano inseriti nel file PRI con tutte le loro giuste qualified variant?

La cosa più semplice è quella di mettere tutti i file risorsa nella cartella del progetto, o in una qualsiasi cartella contenuta in essa (ad esempio /Assets/Images) e inserire le qualified variant direttamente nel nome del file:

Oppure utilizzare delle cartelle che per nome hanno le qualified variant o ancora meglio un miscuglio di entrambe le tecniche:

E' utile notare che è sempre possibile inserire la suddetta struttura dentro una qualsiasi cartella contenuta nella cartella del progetto, o addirittura inserire altre cartelle all'interno della struttura stessa:

Per cui, ad esempio, il file /assets/Localized Images/it/contrast-high/MyImage.scale-100.jpg è del tutto equivalente al file MyImage.lang-it.contrast-high.scale-100.jpg .

L'ordine in cui compaiono le qualified variant è del tutto irrilevante, ad esempio MyImage.lang-it.contrast-high.scale-100.jpg è del tutto equivalente al file MyImage.scale-100.lang-it.contrast-high.jpg o ad ogni altra permutazione.

Ora che abbiamo illustrato la Gestione delle risorse in una Windows Runtime app, spostiamo la nostra attenzione sui file di tipo .resw e sull'uso di XAML x:Uid.

Nonostante la differenza di nome dell'estensione, il formato dei file di tipo .resw è del tutto identico a quello dei più tradizionali .resx, con la notevole eccezione del fatto che i file .resw possono contenere solo stringe e file path.

Visual Studio offre un comodo editor per la creazione e modifica di file di questo tipo:

Tali valori possono essere usati direttamente da codice XAML:

<TextBlock x:Uid="MyTextBlok" Text="This text will be shown at design time" />

A runtime la proprietà Text del TextBox con x:Uid pari a "MyTextBox" assumerà il valore corrispondente al valore dell'elemento contenuto nella risorsa che ha per nome l'unione del valore di Uid, del punto (.) e del nome della proprietà:

E' importate qui ricordare che nel codice XAML è comunque necessario assegnare un valore alla proprietà (nel nostro esempio "This text will be shown at design time") affinché sia possibile vederlo a design time.

Ovviamente è anche possibile leggere tali valori da codice, tipicamente in un ViewModel, bindato a qualche elemento XAML della UI.

Anche in questo caso, per maggiori Informazioni date un'occhiata qui: How to load string resources (XAML).

That's all folks! Happy coding. J

 

Back To the Future: Windows Batch Scripting & ASP.NET vNext

Nell'ultimo TechEd è stata presentata l'anteprima della prossima versione di ASP.NET. La cosa davvero spettacolare è che, sin da subito, il codice è disponibile pubblicamente su GitHub (https://github.com/aspnet).

Per ogni informazione rimando all'ottimo articolo di Jon Galloway (http://weblogs.asp.net/jongalloway/a-30-minute-look-at-asp-net-vnext).

Studiando la materia mi sono imbattuto in un paio di file batch (.cmd) e sono dovuto tornare a scartabellare gli "antichi testi" per poterne comprendere il contenuto.

Per chi magari non si è mai imbattuto negli esoterismi del Windows Batch Scripting, qui di seguito spiego e interpreto il codice di un importante comando: KVM (K-Runtime Version Manager).

Come primissima cosa, una curiosità: Il motivo per cui la lettera "k" è onnipresente deriva dal fatto che inizialmente ASP.NET vNext si chiamava Project-K, da cui si ha:

  • Il Runtime, chiamato K-Runtime o KRE, di cui si possono avere contemporaneamente varie versioni, una per ogni istanza di applicazione.
  • Il Version Manager, chiamato KVM, che serve alla gestione dei diversi KRE disponibili. E' uno script PowerShell che viene lanciato da riga di comando tramite l'omonimo comando KVM.cmd.
  • Il Package Manager, chiamato KPM, che serve alla gestione dei NuGet Package. Chiama il Loader con appositi parametri tramite l'omonimo comando KPM.cmd.
  • Il Loader, chiamato KLR, è in grado di assolvere a molti compiti, tra i quali:
    • Installare/ripristinare i package.
    • Fare il bootstrap per l'esecuzione dell'applicazione.
    • Fare la Build dell'applicazione (cosa non strettamente necessaria per eseguire l'applicazione, che è una delle novità di ASP.NET vNext)

Per una maggiore comprensione delle varie componenti e di come queste interagiscono fra loro, vi invito a leggere la descrizione dettagliata della struttura e dell'architettura del K-Runtime, scritta da David Fowler: https://github.com/aspnet/Home/wiki/KRuntime-structure.

E' chiaro che molti di questi passaggi, ora che è uscita la CTP di Visual Studio 14, vengono automaticamente eseguiti tramite Visual Studio, ad esempio quando viene chiesta l'esecuzione dell'applicazione tramite il classico F5. Ciò non di meno, visto che siamo agli esordi di una nuova versione che per molti aspetti è radicalmente diversa da quella attuale, è importante capire cosa gira dietro le quinte. Anche perché uno degli obiettivi di ASP.NET vNext è quello di offrire una completa esperienza di sviluppo anche a riga di comando senza la necessità di usare Visual Studio (che rimane comunque lo strumento principe di sviluppo).

Fatte quindi le dovute premesse, passiamo dunque a parlare di Windows Batch Scripting, analizzando il contenuto di uno dei comandi che abbiamo a disposizione: KVM.cmd. La sua comprensione ci renderà poi facile analizzare autonomamente gli altri comandi.

KVM.cmd

E' il comando che lancia lo script PowerShell del Version Manager. Per chi eventualmente si domanda a che serve un comando che lancia uno script PowerShell, rispondo subito che il comando è indispensabile sia perché ingloba una serie di parametri di avvio necessari al corretto funzionamento di PowerShell (vedi ad esempio l'execution policy che per essere unrestricted deve necessariamente essere presente come parametro di avvio), sia perché alla fine dell'esecuzione dello script il comando si incarica di avviare un ulteriore comando, se presente, chiamato run-once.cmd.

Vediamolo nel dettaglio:

Nella riga 3 viene lanciato PowerShell con alcuni parametri di startup:

  • -NoProfile per evitare il caricamento del profilo utente.
  • -NoLogo per evitare la visualizzazione del banner di copyright di PowerShell.
  • -ExecutionPolicy unrestricted per abilitare lo script ad eseguire alcune funzioni che altrimenti sarebbero non autorizzate.
  • -Command che dichiara tre comandi da eseguire entro PowerShell, separati da punto e virgola:
    • [System.Threading.Thread]CurrentThread.CurrentCulture = ' '
    • [System.Threading.Thread]CurrentThread.CurrentUICulture = ' '
    • & '%~dp0kvm.ps1' %*

Per quanto riguarda i primi due comandi PowerShell, altro non fanno che impostare la CurrentCulture e la CurrentUICulture.

Per quanto invece riguarda il terzo comando, che a una prima lettura mi ha lasciato un po' perplesso e mi ha obbligato a ripassare i "sacri testi" di Windows Batch Scripting e PowerShell, abbiamo due elementi:

  1. & '%~dp0kvm.ps1'
  2. %*

Il primo elemento è evidentemente il nome dello script che PowerShell deve eseguire, visto che finisce per ps1. E' utile notare che, affinché PowerShell possa eseguire effettivamente uno script, devono essere soddisfatte le seguenti condizioni:

  • La Execution Policy consenta l'esecuzione di script (e in questo caso lo è poiché PowerShell viene per l'appunto lanciato in modalità unrestricted).
  • Lo script venga dichiarato comprensivo del percorso completo (drive:\dirPath\Filename.extension).
  • Se il percorso contiene degli spazi deve essere virgolettato e anteceduto dal Call Operator (&) affinché PowerShell interpreti l'elemento non come semplice stringa ma come percorso completo dello script da eseguire

Posto che all'interno di un comando %0 rappresenta il nome del comando stesso mentre %1 … %9 rappresentano gli argomenti passati al comando, la sequenza %~ seguita da una serie di opzioni (in questo caso pd) e terminata dal numero del parametro (in questo caso proprio il parametro 0) consente di estrapolare il path relativo al comando stesso.

Il secondo elemento è invece semplicemente il passaggio allo script PowerShell di tutti gli argomenti passati da riga di comando al lancio del comando kvm.cmd, in quanto %* è solo il modo abbreviato di scrivere %1 %2 %3 … %9

Vediamolo meglio in un caso esemplificativo, ipotizzando che la cartella che contiene il comando KVM.cmd e lo script kvm.ps1 sia "C:\Users\Nick\.kre\bin" e che tale path sia presente nella variabile di ambiente %PATH% e che venga eseguito (da una qualsiasi directory) il comando kvm list.

Allora & '%~dp0kvm.ps1' %* sarà pari a: 'C:\Users\Nick\.kre\bin\kvm.ps1' list

Al completamento dello script PowerShell (che durante la sua esecuzione potrebbe aver costruito un comando run-once.cmd), alle righe 5-7 tale comando, se esiste, viene eseguito e poi cancellato.

That's all folks, happy coding!

Online Slide e Demo della mia sessione a CDays14 - Milano


Le slide e la demo solution della mia sessione ai Community Days 2014 di Milano sono online: http://www.communitydays.it/events/2014/misc06/

Windows Phone Template Selector, a Design Time Solution

In questo post spiegherò come modificare il DataTemplateSelector descritto da WindowsPhoneGeek per ottenere i seguenti benefici e miglioramenti:

  • Spostare le definizioni dei DataTemplate dalla ListBox alle risorse della pagina o dell'intera applicazione
  • Vedere il risultato della modifica dei data template a design time.

Prima di modificare il codice, vediamo come funziona un DataTemplateSelector. Con Silverlight per Windows Phone non abbiamo a disposizione una classe nativa di tipo DataTemplateSelector, come in WPF, quindi abbiamo bisogno di costruircela da zero.

Ipotizzando di avere:

  • Una ListBox
  • Una ObservableCollection di Item come source della ListBox
  • Degli item che possono essere di diverso tipo, ad esempio A, B or C, con una proprietà dell'Item che contiene un valore che ne identifica il tipo.
  • Abbiamo un data template per ogni tipo di Item

L'obiettivo è quello di mostrare nella lista ciascun item utilizzando il data template corrispondente al tipo di item, come mostrato in figura:

Per ottenere tale risultato, dobbiamo impostare la proprietà ItemTemplate della ListBox a qualcosa che cambia dinamicamente a runtime, sulla base del valore contenuto nella proprietà che descrive il tipo di item:

Quindi "SomeMagicElement" dev'essere qualcosa che abbia:

  • Un evento che venga chiamato ogni qual volta un item dev'essere renderizzato;
  • Una proprietà Content che contenga il riferimento all'item che dev'essere renderizzato;
  • Una proprietà DataTemplate che si possa dinamicamente impostare attraverso una nostra logica ogni volta che viene scatenato l'evento.

E qui calza a pennello la classe ContentControl, osservando la sua definizione:

Grazie alla natura di XAML, bastata sulla composizione recursiva dell'interfaccia utente, possiamo tranquillamente utilizzare questo component come DataTemplate dell'ItemTemplate della ListBox.

L'unica cosa che manca è il punto 3, ma possiamo implementarlo con una classe derivata da ContentControl, che chiamiamo "DataTemplateSelector", nella quale facciamo l'override del metodo OnContentChanged aggiungendo una chiamata al metodo "SelectTemplate", nel quale viene implementata la logica di selezione del data template da utilizzare:

Questa però non si rivela una buona scelta perché nella nostra applicazione possiamo avere svariati usi del DataTemplateSelector, con tipi diversi e logiche diverse. Un approccio migliore è quello di creare una classe astratta con un metodo virtuale, in modo da poter derivare da essa una varietà di selettori personalizzati, per ogni necessità.

Una prima implementazione di tale classe astratta è la seguente:

Qui di seguito un esempio di un selettore personalizzato:

Si può facilmente notare che è una classe derivata dalla classe astratta DataTemplateSelector e che è stato fatto l'override del metodo SelectTemplate.

Quello che però a prima vista è poco chiaro è il motivo per il quale sono state aggiunte le tre proprietà di tipo DataTemplate. Il motivo è presto detto e risiede nel modo in cui vengono passate le definizioni dei data template tramite XAML:

La proprietà DataTemplate dell'ItemTemplate viene impostata con una istanza del CustomTemplateSelector, e al suo interno vengono impostate le proprietà DataTemplateA, DataTemplateB e DataTemplateC. In questo modo il CustomTemplateSelector può usare i valori contenuti in quelle proprietà per restituire il data template associato ad ogni tipo di item.

E con questo termina la spiegazione di quanto proposto da WindowsPhoneGeek nel suo articolo.

Ciò non di meno, permangono due problemi di non poco conto:

  • Non è possibile visualizzare la ListBox a design time ed è quindi necessario avviare l'applicazione per testare le modifiche ai data template, con grande dispendio di tempo.
  • Le definizioni dei data template sono inserite all'interno della ListBox. Se abbiamo più di una ListBox nella nostra applicazione che utilizza gli stessi data template avremo necessariamente una duplicazione di codice, e questa non è mai una buona cosa.

Qui di seguito l'elenco e la spiegazione delle modifiche da me apportate al fine di risolvere entrambi I problemi.

Prima di tutto, utilizziamo un contenitore per il DataContext della pagina (una classe ViewModel, in gergo MVVM…):

Poiché non vogliamo che il DataContext venga impostato solo a runtime, non è possibile utilizzare la classica modalità da code behind:

Andiamo quindi a definire il DataContext della pagina direttamente in XAML. Per fare ciò, dobbiamo definire innanzitutto un nuovo namespace e tramite questo andiamo a impostare la proprietà DataContext della pagina stessa:

In questo modo la classe MainViewModel viene istanziata a design time. Ciò nonostante non saremo ancora in grado di vedere nulla perché l' observable collection non sarà stata ancora inizializzata. Per aggiungere alcuni dati di prova possiamo utilizzare un trucchetto: basterà testare la proprietà statica "IsInDesignModeProperty" della classe statica "DesignerProperties" all'interno del costruttore di MainViewModel e se vero chiamare il metodo "LoadFakeData":

Questo risolve completamente il primo problema perché è ora possibile visualizzare la ListBox e le eventuali modifiche ai data template direttamente a design time:

Per quanto invece riguarda il secondo problema, abbiamo bisogno di modifiche più radicali perché dobbiamo cambiare il modo in cui il nostro "CustomTemplateSelector" ottiene le definizioni dei data template. Infatti, spostando tali definizioni fuori dalla ListBox perdiamo la possibilità di impostarne le proprietà.

La soluzione sta nel fare a meno di tali proprietà, andando a recuperare le definizioni cercandole direttamente nei dizionari delle risorse della pagina e/o dell'applicazione. Ciò però pone subito due nuovi problemi da risolvere:

  1. Dobbiamo in qualche modo mantenere traccia delle definizioni trovate, senza doverle ricercare ogni volta visto che il "CustomTemplateSelector" verrà richiamato molte volte, una per ogni volta che la ListBox ha bisogno di renderizzare un item. In caso contrario si avrebbe una sicura penalizzazione delle prestazioni.
  2. Ottenere il riferimento al dizionario delle risorse dell'applicazione, all'interno del metodo "SelectTemplate" è relativamente facile, ma ottenere quello relativo al dizionario delle risorse della pagina lo è molto meno.

Per risolvere il primo basta aggiungere un dizionario nella classe astratta:

Tale dizionario conterrà I risultati delle ricerche effettuate, in modo da non doverle ripetere.

Il secondo problema si risolve cercando prima nel dizionario delle risorse dell'applicazione, infine utilizzando il metodo "GetParent" della classe statica "VisualTreeHelper", a partire dal contenitore dell'item da renderizzare, fino alla pagina che contiene la ListBox e quindi al dizionario delle risorse ti tale pagina:

Avendo quindi spostato le definizioni al di fuori della ListBox, in questo caso dentro le risorse della pagina, si ha:

Con il nuovo DataTemplateSelector dotato di dizionario e metodo di ricerca:

Otteniamo un "CustomTemplateSelector" molto più pulito perché contenente solo la logica di selezione del data template:

Qui potete scaricare la soluzione completa: http://sdrv.ms/1lGje5J

That's all folks!

WebAPI e Azure Worker Role – RTM Workaround

Per chi volesse seguire il bel tutorial Host ASP.NET Web API in an Azure Worker Role di Mike Wasson, ci sono alcune cose da fare ora che non è più in preview ed è uscita la versione RTM in occasione del rilascio pubblico di Visual Studio 2013.

Come prima cosa, il comando da Package Manager Console non contiene più l'opzione –pre (proprio perché non è più una preview):

PM> Install-Package Microsoft.AspNet.WebApi.OwinSelfHost

E fin qui, tutto facile.

Il problema si pone cercando di avviare la solution, che va in errore.

Il che deriva dal pacchetto NuGet che erroneamente applica una versione di System.Web.Http.Owin(Version 5.0.0.0) che dipende da Microsoft.Owin(Version 2.0.0.0) che è diversa dal file installato, ovvero Microsoft.Owin(Version 2.0.1.0).

In effetti tale dipendenza è facilmente verificabile usando Reflector:

Come riportato nella documentazione .NET, Specifying assembly binding in configuration files, in questi casi è sempre possibile utilizzare il binding redirect per specificare manualmente l'effettiva versione da utilizzare:

<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="2.0.1.0" />
</dependentAssembly>


Quindi per risolvere il problema basta aprire il file appConfig del progetto WebApiRole:

e aggiungere le seguenti righe:

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="2.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Con queste modifiche, l'esempio di un servizio WebAPI hostato in un Azure Work Role dovrebbe proprio funzionare.

Happy Coding!

Gestione delle password con KeePass

Un Anello per domarli, Un Anello per trovarli, un Anello per ghermirli e nel buio incatenarli…

Premessa
che si può saltare a piè pari…

Se solo si potesse fare a meno delle password! La biometrica potrebbe essere la soluzione, ma al momento la sicurezza connessa all'uso di apparecchi per la rilevazione delle impronte digitali e quant'altro sia a portata di tasca e comunque disponibile nei nostri device è del tutto insufficiente per proteggere le nostre informazioni.

Chiunque usi la rete si trova molto presto a dover gestire il login di molteplici siti, ciascuno dei quali richiede la registrazione e quindi poi l'autenticazione per l'accesso.

Ma non tutti i siti sono della medesima importanza, e molto genericamente li possiamo suddividere per categorie di rischio:

  1. Siti che offrono informazioni liberamente accessibili a tutti.
  2. Siti in cui inseriamo del contenuto.
  3. Siti che forniscono servizi a pagamento che non siamo autorizzati a fornire ad altri.
  4. Siti che forniscono servizi finanziari.

E' chiaro che è una super semplificazione, ma serve solo per ricordare che l'eventuale compromissione della sicurezza di una password produce effetti molto diversi a seconda del sito al quale è stata applicata. Chiaro che se si usa una sola password per tutto, allora si è proprio in cerca di guai. Ma anche l'uso di diverse password, una per ogni "livello di rischio", non è una buona idea. La cosa migliore è quella di avere una password diversa per ogni autentificazione, ma tenerle a memoria è pressoché impossibile.

Poi c'è la questione che riguarda il recupero delle password "dimenticate" (cosa che a me capita più di sovente, ed è il motivo della ricerca di una soluzione più efficiente e sicura, che mi porta alla scrittura di questo post).

Quasi sempre le password possono essere recuperate inserendo il proprio indirizzo di posta elettronica, a cui viene inviata una email con un link alla pagina web di reimpostazione della password.

E qui viene il punto critico: chi si impossessa della nostra email può fare dei danni mostruosi. Può richiedere la password di molti dei siti a cui siamo registrati, cambiare la password e fare il comodo suo a casa nostra.

Io per i siti di home banking non ho problemi (o almeno conto di essere mediamente sicuro) perché uso la chiavetta che genera la "one time password" e fino ad oggi per gli altri siti ho utilizzato una strategia a livelli, a secondo del rischio. Ma così facendo ho comunque troppe password da tenere a mente e spesso mi sbaglio quando torno dopo molto tempo su siti la cui appartenenza a uno dei livelli di rischio non è così evidente. E mi trovo così a dover spesso richiedere il cambio di password perché me la son dimenticata e non mi va di fare troppi tentativi.

Ma la cosa più sbagliata del mio metodo è che si dovrebbe usare una chiave diversa per ogni sito.

La gestione integrata delle password

Oggi ho chiesto consiglio ai miei amici, e dopo aver ascoltato i loro consigli ho deciso di utilizzare KeePass.

E' un programma gratuito per Windows Desktop che registra le nostre chiavi (Utente/Password) in un database criptato.

Per usarlo anche con Windows Phone è disponibile un programma a pagamento (0,99 €) che si chiama 7Pass.

L'uso di KeePass è banale ma molto piacevole.

In estrema sintesi:

  1. Si crea un database (con una password bella lunga perché chi ha l'accesso al database accede a TUTTE le nostre password li registrate:


    Da notare che 7Pass non è compatibile con l'uso del key file e/o il Windows User account

  2. Lo si salva su SkyDrive, in modo da poterlo aprire dai diversi device (compreso il Windows Phone via 7Pass).
  3. Si crea una chiave, ad esempio per facebook, utilizzando il password generator per generare una chiave random:


  4. Si apre sul web la pagina di cambio password
  5. Ci si sposta sulla pagina di KeePass, si seleziona CTRL-V (che su KeePass esegue l'Auto-Type)
  6. E come per magia si torna automaticamente sulla pagina web dove i campi Utente e Password vengono compilati da KeePass. Ove non sia possibile (ad esempio utilizzando 7Pass sul Windows Phone) basta fare copia e incolla.

     

  7. Stessa cosa per l'autenticazione.

Da adesso in poi, niente richieste di password dimenticata, almeno per me!

Community Days

Si è conclusa la tre giorni dei Community Days di Roma, prima volta nella capitale di un evento che riunisce le Community italiane sulla tecnologia Microsoft.

E' stata un'occasione unica di condividere la mia passione con tanti amici, e un ringraziamento particolare va a Giorgio di Nardo e specialmente a Luca Cestola per avermi aiutato a finire la mia ultima demo, mentre eravamo alla postazione di registrazione all'evento :-)

L'affluenza è stata notevole, e l'atmosfera molto bella con gente che mostrava di apprezzare la qualità delle sessioni e dell'evento in generale.

Devo dire, in tutta sincerità, che l'idea di condividere l'onere e l'onore di fare una sessione in presenza di tante persone e in un evento costellato di speaker di assoluto rilievo mi ha fatto tremare le gambe e vivere l'attesa con una certa dose d'ansia.

Alla fine credo di aver fatto una buona sessione, anche se come sempre il tempo è tiranno e si deve cercare di dire lo stretto necessario in un tempo necessariamente troppo breve.

Per questo motivo, oltre a rimandare alle slide e ai sorgenti dei progetti dimostrativi appena pubblicati nel sito di Community Days, ho intenzione di scrivere alcuni post per riprendere e approfondire le tematiche illustrate nella mia sessione.

Un ringraziamento speciale a Daniele Bochicchio e Andrea Saltarello per aver portato Community Days finalmente anche a Roma, e più in generale per tutto quello che fanno nell'ambito della Community.

Un saluto a tutti gli amici coi quali ho passato tre giorni bellissimi, nell'evento e nelle cene, specialmente a Lorenzo Barbieri, gran cerimoniere delle community italiane!

Ora tocca a me spostarmi, ci si vede a Milano lunedì prossimo, al Windows Phone Day!

«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011