Technology Experience
.NET World

Windows 8: occhio a cio’ che fate nei Background Task

Sviluppando una mia app Windows 8 mi è capitata una cosa strana riguardante i Background Task. Se volete capire cosa sono, a cosa servono e come si sviluppano i Background Task vi rimando a questi due post (in inglese) dell’amico Matteo Pagani: post 1 e post 2.

Quello che mi è accaduto è che il debugging effettuato tramite Visual Studio 2012 non è veramente la stessa cosa che accade quando invece il codice gira realmente tramite l’app deployata. Ora vi spiego.

Immaginate di sviluppare un’app che vi fa il countdown relativamente ad un certo evento. Oggi è il 14 Gennaio. Supponiamo di voler impostare un countdown per San Valentino. Il countdown appare sulla tile dell’app stessa. Quindi oggi apparirebbe una cosa tipo “mancano 30 giorni a san valentino”, domani vedreste “mancano 29 giorni a san valentino”, e così via.

In pratica, il Background Task della mia app, che gira ogni 15 minuti, non fa altro che aggiornare la tile riportando il tempo rimanente. Le informazioni sull’evento sono banalmente scritte in un file .txt, che viene creato nel momento in cui scegliete l’evento. Quindi, per riassumere, ecco il codice contenuto nel metodo Run del Background Task.

public async void Run(IBackgroundTaskInstance taskInstance)
{
    BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

    try
    {
        var container = Windows.Storage.ApplicationData.Current.LocalFolder;
        var file = await container.GetFileAsync("File.txt");
        var lines = await Windows.Storage.FileIO.ReadLinesAsync(file);
        var header = lines[0];
        var time = DateTime.Parse(lines[1]);

        if (time > DateTime.Now)
        {
            var ts = time.Subtract(DateTime.Now);
            string content = ts.TimeSpanDescription(" all'evento scelto. Non mancare!");
            TileHelper.UpdateTileWidePeekImage01("Assets/WideLogo.reminder.png", header, content);
        }
        else
        {
            TileHelper.UpdateTileWideImage("Assets/WideLogo.scale-100.png");
        }
    }
    catch (Exception)
    {

    }

    deferral.Complete();
}

 

Questo è il codice corretto, che gira senza problemi, per cui sa volete prendere ispirazione, fatelo pure. Occhio però a come usate la keyword await, necessaria per eseguire i metodi asincroni. Stupidamente, io in una prima versione del codice non la usavo, ed usavo invece il metodo GetResults(). Per spiegarmi meglio, ecco il pezzetto di codice incriminato:

var lines = Windows.Storage.FileIO.ReadLinesAsync(file).GetResults();

Ripeto il concetto: invece di usare await, ho chiamato GetResults(), convinto – chissà perchè – che facessero la stessa cosa. Purtroppo questa cosa è stata ereditata da un pezzetto di codice scritto mesi fa, quando avevo ancora a che fare con le versioni beta di Windows 8 e Visual Studio 2012 11. La cosa bella è proprio questa: questo codice qui sopra quando eseguito da Visual Studio gira senza problemi (dentro l’oggetto lines avete la List<string> delle righe contenute nel file di testo appena letto), mentre quando gira “in produzione” si schianta. Ci ho litigato per un weekend prima di raggiungere la soluzione, proprio perchè dovevo aspettare realmente 15 minuti prima di verificare il comportamento.

Anche in questo caso, tutto è bene ciò che finisce bene.

Send to Kindle
.NET World

App per lo Windows Store che fanno uso delle Bing Map

Sono incappato in un problema realizzando un’app Windows 8 per lo Windows Store. L’app è Gps Coordinate Converter, e ad oggi è regolarmente pubblicata. In pratica accadeva che sui sistemi Windows 8 x86 e x64 (in pratica i classici PC desktop, notebook ed ultrabook) girava senza presentare problemi, mentre sui device Windows RT (con architettura ARM) l’app si schiantava all’avvio.

La cosa è allo stesso tempo chiara ma insidiosa.

Dunque: innanzitutto, quando in un’app per lo Windows Store aggiungiamo nelle reference il componente Bing Map, siamo costretti ad impostare nelle proprietà del progetto stesso un’architettura: o x86, o x64 oppure ARM. Non possiamo impostare Any CPU, dal momento che il progetto a questo punto non compila proprio. Io evidentemente a suo tempo selezionai x64: in questo modo compilavo e potevo tranquillamente far girare l’app sul mio notebook.

Quando poi arriva il momento di produrre il package da uploadare sullo Store, bisogna nuovamente selezionare l’architettura del package stesso. Questa cosa può magari sfuggirvi come è sfuggita a me, perchè siete convinti che il package viene prodotto in base a ciò che viene impostato nelle proprietà del progetto, ma non è così. Perciò ricordatevi che a seconda di cosa selezionate in questo momento, l’app potrà essere trovata sullo Store dai diversi device Windows. Mi spiego meglio. Supponiamo di aver fatto la build per x64, e poi di produrre il package selezionando Any CPU. Se approvata, l’app potrà essere trovata anche da tablet Windows RT (Asus Vivo RT o Surface RT, per intenderci): il risultato è che l’app verrà scaricata ed installata, ma si schianta quasi immediatamente…il tempo di vedere lo splash screen. Quindi bisogna stare attenti: se nelle proprietà del progetto mettete x64, dovete poi produrre il package per x64. Se nelle proprietà mettete ARM, dovete produrre il package per ARM.

Come gira il Windows App Cert Kit ?
Ok, passiamo oltre. Come ben sapete, prima di uploadare un’app sullo Store dovete farla validare dal WACK, che vi trova eventuali problemi prima di passare dalla trafila della certificazione. Ovviamente, il WACK è in grado di mettere sotto torchio la vostra app solo quando state producendo il package corrispondente all’architettura del vostro pc che state usando per sviluppare. Morale: quando compilate l’app e producete il package per x64, il WACK sarà in grado di testare l’app, altrimenti no. Nel primo caso, una volta terminata la creazione del package, vi verrà chiesto se volete far girare il WACK. Nel secondo caso, invece, vi verrà solamente fornito il link alla cartella nel quale è contenuto il package.

Upload dei diversi package differenziati per architettura del processore
Ok, supponiamo di aver prodotto due package differenti per la stessa app: un package è specifico per x64, l’altro package per ARM. Come si fanno ad uploadare sullo Store? E’ molto semplice: andate nel dashboard del vostro Windows Store Dev Center, create l’app (o semplicemente una nuova release come ho dovuto fare io per risolvere il mio problema) e quando dovete uploadare i package (files con estensione .appxupload) semplicemente fate l’upload di tutti i package per le diverse piattaforme. Direi nulla di più semplice.

Send to Kindle
Hardware

Il mio ultimo acquisto: Dell XPS 12

Vi ricordate questo mio post del 29 Settembre scorso? Incredibilmente sono riuscito in un modo o nell’altro a smarcare tutti e tre gli acquisti, anche se devo confessarvi che sono stato abbondantemente aiutato da fonti esterne. Riassumendo:

  • sono entrato in possesso di un Asus Vivo RT, un tablet Windows RT con cui mi trovo molto molto bene, e che utilizzo per sviluppare app e durante il tempo libero. Bel prodotto!
  • sono entrato in possesso di un Nokia Lumia 920: questo grazie all’azienda in cui lavoro, Brain-Sys, che mi ha upgradato il cellulare aziendale, da un Blackberry Curve 9300 (che mi ha fedelmente accompagnato per circa tre anni) all’ultra-gioiello di casa Nokia. Veramente una bomba, nulla a che vedere con il mio vecchio Windows Phone 7
  • ho acquistato, e finalmente arriviamo all’oggetto in questione, un Dell XPS 12, l’ultrabook pronto a diventare tablet, per citare proprio Dell

Ma andiamo con calma. Il tutto comincia il 29 Ottobre scorso, con una breve chattata via GTalk con mio fratello:

La chattata fa avanti per pochi minuti.

In quel periodo stavo cercando un ultrabook Windows 8, per sostituire il mio vecchio Acer acquistato nell’estate 2009. Il mio obiettivo era avere un ultrabook Windows 8 (evitando proprio Acer, per il semplice fatto che dopo un anno di vita le batterie hanno una durata di circa 10 minuti), possibilmente convertibile in tablet. Non avevo particolari esigenze: non era obbligatorio avere un SSD piuttosto che un "più affidabile” HDD, non mi interessava avere 8 o 16GB di RAM, non avevo particolari esigenze sul display, sulla tastiera o cose simili. L’unica cosa che mi interessava era avere un ultrabook/tablet, schermo touch, Windows 8. Il primo periodo è stato deludente: prima di questo famigerato 29 Ottobre, ho passato qualche sabato a girovagare per i centri commerciali alla ricerca di un ultrabook, con scarsi risultati. Ne avevo parlato un pochino qua.

Tutto questo, ripeto, fino al 29 Ottobre, data della chattata qui sopra.

Di questo Dell XPS 12 mi sono innamorato fin dal primo momento. Era proprio quello che cercavo. Ultrabook con schermo touch ribaltabile per trasformarlo in tablet. Aggiungiamo: display Full-HD 1920×1080, 12 pollici, 2 porte USB 3.0, tastiera retroilluminata, disco SSD, leggero e maneggevole, prezzo competitivo (ma decisamente più alto rispetto a quanto ero abituato a spendere in passato per un portatile), etc. etc.

Ci penso un pochino e soprattutto grazie all’intervento di mio fratello, procedo all’ordine. Il sito Dell recita che i tempi di consegna sono di circa 6-8 giorni. Un pochino falso, diciamo, ma sopprassediamo. L’ordine parte il 31 Ottobre. Riceverò il Dell il 22 Novembre: tre settimane di attesa. Tra l’altro, il Dell arriva a casa mentre io sono in giro per lavoro, saltando da una trasferta all’altra (Valtellina, 3 giorni, per lavoro; Bologna, durante il weekend, per impegni personali; Cuneo, 4 giorni, di nuovo per lavoro).

Il primo impatto è spettacolare. Riassumendo: il Dell XPS 12 è una bomba. Veloce, leggero, ottimi materiali, schermo eccezionale, utilizzo sia in modalità ultrabook che in modalità tablet da goduria. Sulla modalità tablet aiuta moltissimo Windows 8, la cui interfaccia è decisamente la cosa giusta. Insomma, totalmente soddisfatto dell’acquisto!! Lo trovo lo strumento ideale sia per lavoro, sia per il tempo libero. Io lavoro per il 90% del mio tempo a casa, usando il desktop, ma poi la sera mi metto sul Dell, sia per altri impegni (app per Windows 8, la mia attività all’interno di Piloti Virtuali Italiani, etc. etc.), sia per qualche partitina. Chiaramente, puntualizzo, è un ultrabook, non un tablet puro, per cui il peso non lo rende agevole come un Asus Vivo RT o un iPad. Ma sono cose ben diverse, spero l’abbiate capito, questo.

Tutto questo fino al guasto delle porte USB!!

Sabato 8 Dicembre succede il patatrac! Per la cronaca: già risolto, grazie all’intervento veloce e tempestivo dell’assistenza Dell (bravissimi, eccezionali, vedere dopo).

Insieme al Dell, ho acquistato un MyPassword da 1TB con USB 3.0.

Questo chiaramente per sopperire all’SSD da 128GB, sufficiente per contenere Windows 8 e tutti gli strumenti con cui lavoro. Insomma, quel disco è il famigerato “disco dei dati”. Quel sabato infilo la porta USB nell’ultrabook ed il disco non viene rilevato. Il disco viene alimentato, vedo il led accendersi, ma non compare in Risorse del Computer. Insospettito, provo varie chiavette USB, periferiche varie. Nulla, il PC non rileva più nulla. Riavvio, faccio 10.000 prove e tentativi. Nulla, sembra non andare più. Non riesco nemmeno a fare il boot da USB, prova del fatto che Windows non c’entra niente con la questione. Tra l’altro vedo che la periferica “Intel USB 3.0 Extensible Host Controller” in “Gestione Dispositivi” è evidenziata con un punto esclamativo giallo: Windows non riesce ad attivare la periferica (codice errore 10). A questo punto comincia il weekend più deprimente degli ultimi tempi, e non vedo l’ora che arrivi lunedì per far intervenire l’assistenza Dell. Mio fratello, sopravvissuto un paio d’anni fa ad una Odissea con Dell, ha avuto l’oculatezza di inserire nell’ordine due voci importanti: l’assistenza 1 Yr ProSupport and Next Business Day On-Site Service, e soprattutto l’assistenza 1 Yr Accidental Damage Protection (danni non volontari, ma comunque causati dall’utente).

E qui arriviamo alla storia recente. Lunedì 10 Dicembre, alle 9 della mattina, chiamo l’assistenza, e faccio due telefonate. La prima è decisamente con un incompetente: mi chiede se il Dell XPS 12 è un desktop oppure un portatile, mi chiede se ha su Windows XP oppure Windows 7, si collega da remoto e cerca di reinstallare i driver dell’Intel USB 3.0 Extensible Host Controller. Non trova i driver, li deve chiedere al reparto ingegneristico. Cerco di spiegargli che comunque le porte USB non funzionano nemmeno da BIOS, perchè non riesco a fare il boot di Clonezilla, ad esempio. Niente, sembra non capire. Chiudiamo la telefonata con la promessa che mi avrebbe richiamato a breve con qualche news. Tutto questo avviene nella mattinata (ore 9:00 –> ore 10:00). Nel primo pomeriggio richiamo, con l’intento di essere un po’ più burbero. Il secondo interlocutore è più competente: spiego il problema e facciamo qualche tentativo un po’ più a basso livello (aggiornamento del BIOS, tentativi vari). Ma nulla, le porte USB continuano a non funzionare. Ma questa volta le cose accelerano: il tizio al telefono apre un intervento tecnico on-site per il giorno dopo: è prevista la sostituzione della scheda madre.

Martedì 11 Dicembre, all’ora di pranzo, arriva il tecnico. Un ragazzo giovane, dalla faccia che mi fanno pensare “questo è in gamba”. Gioco anche la carta psicologica: indosso una maglietta nera, con una bella scritta in verde: Microsoft. Giusto per mandare un messaggio subliminare: non stai parlando con un loser, so usare i computer da prima che tu nascessi (cit.), per cui non raccontarmi balle.

Ma il tizio è veramente in gamba. In dieci minuti apre l’ultrabook, usando tre cacciaviti diversi, rimuovendo circa 15 vitine. Lo tenevo d’occhio. Senza perdere un colpo, e senza battere ciglio, smonta la mainboard vecchia e sistema quella nuova. Velocemente, senza avere il minimo dubbio. Dico davvero. Rimonta tutto, accende il PC e tutto riprende a funzionare egregiamente. Mi dà dieci minuti di tempo per testare un po’. Inserisco il mio disco esterno MyPassword e funziona. Inserisco le mie chiavette USB e vengono rilevate. Dal momento che è stata sostituita la mainboard, controllo che il processore e la RAM siano le stesse, controllo lo schermo, mi faccio un giro. Ritorno a sorridere, il mio problema è stato risolto.

Detto questo, di tutto questo giro, sono comunque molto soddisfatto. L’XPS 12 è una gran bella macchina, l’assistenza Dell è eccezionale (un po’ meno al telefono, ma superlativa quando interviene).

Ultimi appunti finali

Nel momento in cui vi scrivo ho trovato questa recensione su questo Dell. Ve la segnalo perchè la trovo obiettiva e corretta. Ed ora vi lascio qualche appunto finale, con apprezzamenti e critiche costruttive.

  1. L’XPS 12 ha Bluetooth integrato: questo significa che potete utilizzare in abbinamento un Mouse Bluetooth senza mangiare una delle USB disponibili
  2. La tastiera non è ovviamente full. Quindi non avete tastierino numerico, per esempio, e per muovervi nel testo (home/end/pageup/pagedown) siete costretti ad usare la combinazione con Fn
  3. Occhio alla rotazione del display, che è figa ma è pericolosa allo stesso tempo. Mi spiego: quando uso il Dell XPS 12 come ultrabook e poi lo sollevo, per spostarmi, lo afferro in un modo tale per cui sblocco lo schermo (mano destra in prossimità della parte inferiore destra dello schermo). Per cui se non state attenti rischiate di tenere l’ultrabook con la cornice: meglio evitare. Ma in fondo basta farci l’abitudine!

Buon Dell XPS 12 a tutti, insomma!

Send to Kindle
Hardware

Non capisco l’equivalenza tablet = mobilità. E chi l’ha detto?

E’ passato qualche giorno da quando ho avuto uno scambio di tweet con alcuni follower/following sul discorso tablet, Windows 8, ultrabook ed autonomia delle batterie. Il discorso è piuttosto complesso, e dipende molto dal modo con cui si utilizza un pc, un portatile, un tablet. Ma il concetto di fondo è ben riassunto dal titolo del post. Ovvero: non è assolutamente obbligatorio che un ultrabook/tablet Windows 8 debba venir utilizzato in mobilità. Da cui una semplice deduzione: un ultrabook Windows 8 con un’autonomia di 4 ore è perfettamente in linea con quanto offre il mercato oggi.

Cerchiamo di tornare indietro nel tempo con la mente, e pensiamo ai primi PC e notebook dotati di connettività WiFi. Una bella comodità, senza dubbio, per chi lavora in mobilità. E’ talmente una cosa comoda che oggi ci ritroviamo il WiFi dappertutto, su portatili che mai e poi mai ci capiterà di usare in mobilità. Morale: il WiFi nel 2012 non ha nulla a che fare con la mobilità. Ce l’abbiamo punto e stop, anche se utilizziamo il notebook in ufficio tutti i giorni, come è capitato a me per anni ed anni.

Idem per i tablet Windows 8. E’ verissimo che iPad ha un’autonomia imbattibile. Ma è solo un tablet, nulla di più, nulla di meno. Ci fai solo le “cose da tablet”, punto. Ed il paragone con gli ultrabook è totalmente fuori luogo. iPad è solo un tablet, ripeto, gli ultrabook sono dei veri e propri PC. Se un ultrabook è anche un tablet (come il mio recente Dell XPS 12, tanto per intenderci) non lo paragonerò mai e poi mai con alcun tablet, men che meno con un iPad. Sono due prodotti totalmente diversi.

Il fatto che un ultrabook Windows 8 moderno sia anche touch, e sia anche un tablet, non significa assolutamente che sia la scelta ideale anche per chi lavora in mobilità. Se siete spesso su un treno, in aereo, in automobile, in fiera, un tablet puro, leggero e con una bella batteria è senz’altro la cosa migliore.

Sono pronto a scommettere che entro pochi mesi tutti i notebook/ultrabook avranno schermi touch. Il touch sarà una cosa così naturale che presto saremo qui a dire: ma come cavolo facevamo prima, senza? Ed utilizzeremo il touch sempre ed ovunque, in modo naturale, così come oggi è naturale avere il WiFi, che inizialmente era prerogativa esclusiva dei portatili. Quindi, per favore, non associate tablet ed interazione touch con il concetto di mobilità: non c’entrano assolutamente nulla.

Send to Kindle
.NET World

Creare uno UserControl per Windows 8 app e distribuirlo

Nei giorni scorsi mi sono scontrato con il problema indicato dal titolo del post. La procedura non è poi così diversa da quella a cui ero già abituato:

  • Creare un progetto di tipo Class Library (Windows Store apps)
  • Aggiungere un “New Item” al progetto e selezionare “User Control”
  • Sviluppare il controllo, scrivendo XAML, codice, code-behind, etc. etc.: tutto ciò che volete

Il bello arriva quando volete distribuire il vostro controllo. Normalmente, infatti, compilereste il progetto di cui sopra e dareste in giro l’assembly che avete ottenuto. Quindi, se avete creato un progetto chiamato “CheBelloIlMioControllo”, quando compilate ottenete un assembly chiamato “CheBelloIlMioControllo.dll”.

Non è sufficiente. La sola dll non è sufficiente. Dovete distribuire anche lo XAML relativo ai vostri controlli, e lo dovete fare in un modo piuttosto particolare.

Rispetto alla location in cui si trova l’assembly, dovete:

  • Creare un folder chiamato esattamente come la dll (nel nostro esempio “CheBelloIlMioControllo”)
  • Nel folder di cui sopra dovete copiare i files XAML relativi al controllo

Se il controllo nel vostro progetto è stato creato all’interno di un folder, la struttura di folder diventa: NomeAssembly/NomeFolder/NomeFileXaml.

Ultima cosa assolutamente importante: dovete distribuire anche il file con estensione .PRI, che ha lo stesso nome del nostro assembly.

Ecco un piccolo esempio:

L’assembly si chiama VivendoByteToolkit. I controlli sono stati creati dentro il folder Controls, che quindi contiene i tre files XAML relativi ai tre controlli: CurrencyPicker.xaml, DatePicker.xaml e NumberPicker.xaml.

All’interno del folder VivendoByteToolkit ho inserito il file VivendoByteToolkit.dll e VivendoByteToolkit.pri.

Direi che è tutto.

Send to Kindle
.NET World

WinRT: catturare una foto e salvarla nel roaming folder

Con qualche riga di C# è possibile utilizzare la webcam o la fotocamera del nostro PC/tablet/ultrabook e salvarla all’interno della cartella roaming, che viene automaticamente sincronizzata tra tutti i vostri device Windows 8.

Il codice è piuttosto semplice.

StorageFolder folder =
     Windows.Storage.ApplicationData.Current.RoamingFolder;
CameraCaptureUI dialog = new CameraCaptureUI();

Qui sopra ho istanziato due oggetti che ci serviranno nel codice.

private async void Button_Click_1(
   object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    var file = await dialog.
      CaptureFileAsync(CameraCaptureUIMode.Photo);

    if (file != null)
    {
        string filename = string.Concat
          (Guid.NewGuid().ToString(), file.FileType);
        await file.MoveAsync(folder, filename);
    }
}

La prima cosa che faccio è invocare il metodo CaptureFileAsync. Questo metodo avvia la fotocamera del device, e vi permette di catturare una foto od un video. Se concludete l’operazione con successo (ovvero: se non annullate l’operazione), il vostro file media viene salvato in una cartella temporanea che – stando a ciò che ho letto in giro sul Internet – può venir ripulita dal sistema.

La prima cosa che faccio quindi è spostare il file nella cartella roaming, rinominando il file, dandogli un nome univoco – nel mio caso genero un nuovo Guid, voi potete applicare qualsiasi logica vi venga in mente.

Questo approccio ha diversi vantaggi:

  • salvandola nel roaming folder, le vostro foto/video vengono sincronizzate tra tutti i vostri device Windows 8 (ovviamente se fate login con il vostro Microsoft Account)
  • Se avete MediaElement o Image nel codice XAML, potete far riferimento alle immagini salvate nel roaming folder tramite l’url “ms-appdata:///roaming/nomefile”. Facile e veloce, senza troppi fronzoli

Detto questo, ricordatevi solamente nelle Capabilities della vostra app per abilitare la webcam.

Send to Kindle
Hardware

Windows 8: 40 milioni di copie vendute, ma pc sugli scaffali

E’ di ieri sera la notizia che nel primo mese dall’immissione sul mercato, Windows 8 ha venduto 40.000.000 di copie in giro per il mondo. Qualche fonte:

http://arstechnica.com/information-technology/2012/11/windows-8-sales-are-good-if-not-great-at-40-million-copies-in-the-first-month/

http://phys.org/news/2012-11-windows-sales-million.html

Questo in risposta a tutti quei blog e a quelle più disparate fonti su Internet che invece dichiaravano che le vendite erano di sotto delle aspettative. Eppure, a quanto pare, i notebook e gli ultrabook Windows 8 che si trovano nei negozi rimangono invenduti. Evidentemente, i consumatori preferiscono e vogliono il software, per essere aggiornati, ma non comprano l’hardware.

Io un’idea me la sono fatta, e da qualche settimana, a dir la verità.
Ci sono alcuni fattori da prendere in considerazione.

Innanzitutto, la gente vuole prodotti funzionali e belli. La gente ha capito che Windows 8 è anche per dispositivi touch, siano essi notebook, ultrabook o tablet. Non ne ho la certezza matematica, ma ho la netta sensazione che ad oggi si trovi ben poco, al Mediaworld, al Saturn, all’Unieuro, al Darty, e via dicendo. Ci sono i cari buoni vecchi portatili 15”, senza touch, con Windows 8 installato sopra. Davvero uno scenario triste. Senza parlare dell’importanza del “day-one”: io stesso sono andato in giro per un intero sabato nei centri commerciali più grossi della Lombardia alla ricerca di un notebook/ultrabook Windows 8, trovando praticamente nulla.

Per motivi di lavoro, ho girovagato nella scorsa settimana un po’ i centri commerciali in tre luoghi diversi del Nord Italia (io bazzico da queste parti):

  • in Valtellina
  • a Bologna
  • a Cuneo

In tutti questi tre posti, non ho trovato hardware adeguato, capace di sfruttare le capacità touch di Windows 8. Quindi, lo ripeto, evidentemente la gente preferisce aspettare di vedere qualcosa di bello.

La seconda questione è che secondo me con Windows 7, e di conseguenza l’8, sia cominciato un trend piuttosto particolare. Un trend che va a vantaggio per noi utenti, ma probabilmente un po’ a svantaggio dei produttori. Mi riferisco al fatto che l’uscita di un nuovo sistema operativo Microsoft non scatena per forza l’acquisto di un hardware più potente. Anzi, semmai proprio il contrario. Questo a mio avviso è un concetto molto importante. Attenzione: con “potente” mi riferisco alla velocità della CPU, alla memoria RAM, all’occupazione su disco. Quindi è molto probabile che un utente si tenga il pc che ha già, ci installa sopra Windows 8, e lo usa. Io conosco circa 15 persone che han seguito questo approccio. Mentre una volta avrebbe magari voluto migrare da un dual-core ad un quad-core, oppure passare a 1GB a 4GB di RAM, e via dicendo. Windows 7 ha dato il via ad un’era, secondo me, di “ottimizzazione del software”, al punto che Windows 8 si avvia ed in generale è più performante di Windows 7, a parità di hardware. Quindi un consumer che a casa ha un quad-core e 4 GB di RAM, non sente assolutamente l’esigenza di comprare un pc nuovo; anzi, probabilmente tenta di installare Windows 8 sopra un PC più vetusto, perchè si rende conto che – cavolo – è davvero “fast and fluid”!!! Mio padre, per esempio, usa Windows 8 anche su un vecchio Athlon 64 3800+ con 1GB di RAM, e per le cose che fa si trova più che bene.

E’ vero che Microsoft fa il software, e quindi è più che contenta delle 40.000.000 di copie vendute. Ma l’hardware rimane lì. E questo è colpa dei produttori (in minima parte) e soprattutto colpa di chi deve vendere, che dovrebbero avere hardware da vendere fin dal primo giorno di commercializzazione.

Send to Kindle
.NET World

SwipeCommandHelper, una piccola solution di esempio

Ho messo a disposizione questa piccola solution, da poter scaricare liberamente, per provare in due secondi le funzionalità della SwipeCommandHelper che mi sono creato.

Chiaramente dovete avere Windows 8, Visual Studio 2012 e – volendo – un bel monitor touch (ma non è indispensabile).

L’esempio è chiaramente molto semplice. Il viewmodel espone un’unica proprietà Number, un numero intero, che viene visualizzata sulla UI. Facendo le gesture sulla Grid (che è la parte evidenziata dal colore beige) eseguite i command associati in base alla gesture stessa:

  • Verso l’alto, incrementate il valore di 1
  • Verso il basso, decrementate il valore di 1
  • Verso sinistra, dividete il valore per 2
  • Verso destra, moltiplicate il valore per 2

L’esempio è chiaramente stupido e banale, ma il succo del discorso non è certamente questo. Il punto centrale è poter assegnare dei command in base alla gesture: la complessità dei command dipende chiaramente dal vostro viewmodel. Questo è solo un sample. E – lo ripeto – posso agganciare la gestione dello swipe a qualsiasi FrameworkElement, che sia una Grid, un Button, un’Image, qualsiasi controllo, insomma.

Una cosa importante che voglio aggiungere è che lo swipe funziona anche con il mouse, quindi non è indispensabile avere un display touch per poterlo provare ed usare. Basta trascinare il puntatore del mouse verso una qualsiasi delle quattro direzioni, e secondo WinRT avviene comunque una manipulation.

Send to Kindle
.NET World

Gestire lo swipe nelle quattro direzioni su un qualsiasi elemento della UI

Vi piacerebbe poter gestire lo swipe verso sinistra/destra/alto/basso, su qualsiasi elemento della UI, e sfruttando ovviamente Model-View-ViewModel, per gli amici MVVM? Ovvero, poter scrivere un blocco di XAML così?

<Border Background="Cyan" Width="500" Height="200"
        helper:SwipeCommandHelper.Up="{Binding IncrementCommand}"
        helper:SwipeCommandHelper.Down="{Binding DecrementCommand}"
        helper:SwipeCommandHelper.Right="{Binding MultiplyCommand}"
        helper:SwipeCommandHelper.Left="{Binding DivideCommand}" />

Al Border qui sopra ho dato la possibilità di eseguire un command differente in base a quale tipo di swipe l’utente fa sopra il Border stesso. Se scorro il dito verso l’alto, eseguo l’IncrementCommand. Se lo scorro verso destra, eseguo il MultiplyCommand. E così via. La cosa bella è che la classe SwipeCommandHelper può agganciarsi a qualsiasi oggetto FrameworkElement.

Il codice è abbastanza semplice.

public static class SwipeCommandHelper
{
    public static ICommand GetUp(DependencyObject obj)
    {
        return (ICommand)obj.GetValue(UpProperty);
    }

    public static void SetUp(DependencyObject obj,
        ICommand value)
    {
        obj.SetValue(UpProperty, value);
    }

    public static readonly DependencyProperty UpProperty =
        DependencyProperty.RegisterAttached("Up",
        typeof(ICommand),
        typeof(SwipeCommandHelper),
        new PropertyMetadata(null,
        new PropertyChangedCallback(Setup)));
}

Il codice qui sopra è una semplificazione, e riporta solo la dependency property per gestire lo swipe verso l’alto. La dependency property è UpProperty, ed è di tipo ICommand. Il valore predefinito è null, e quando il suo valore viene modificato viene invocato il metodo Setup(). Questo metodo fa un po’ di code, ma il succo del discorso è che si aggancia all’evento ManipulationStarted del controllo, in modo tale che quando l’utente farà qualche gesture noi potremo intercettare questo evento ed eseguire il command associato. Il codice del metodo Setup() è il seguente:

private static void Setup(DependencyObject obj,
            DependencyPropertyChangedEventArgs e)
{
    FrameworkElement ctl = obj as FrameworkElement;

    if (ctl != null)
    {
        ICommand oldValue = (ICommand)e.OldValue;
        ICommand newValue = (ICommand)e.NewValue;

        if (oldValue == null && newValue != null)
        {
            {
                if (GetAttached(ctl) == false)
                {
                    ctl.ManipulationMode = ManipulationModes.TranslateX |
                        ManipulationModes.TranslateY;
                    SetAttached(ctl, true);
                    ctl.ManipulationCompleted += ctl_ManipulationCompleted;
                }
            }
        }
        else if (oldValue != null && newValue == null)
        {
            ctl.ManipulationMode = ManipulationModes.None;
            ctl.SetValue(AttachedProperty, false);
            ctl.ManipulationCompleted -= ctl_ManipulationCompleted;
        }
    }
}

Aggiungo due note importanti: per default, in Windows 8 su un oggetto sulla UI non si possono intercettare gesture. Con Windows Phone, per esempio, è sufficiente sottoscrivere l’evento ManipulationCompleted ed il gioco è fatto. Con Windows 8, invece, prima dovete impostare il ManipulationMode, poi sottoscrivete l’evento. Per default, ManipulationMode è None, e quindi anche se impazzite a fare gesture sopra l’oggetto, nel codice non accadrà nulla. Ma non abbiate paura: ci pensa il mio codice a fare tutto ciò: non appena associate un command ad uno dei quattro tipi di swipe, vado automaticamente ad impostare il ManipulationMode su TranslateX | TranslateY.

A questo punto non ci resta che scrivere il codice dell’evento ManipulationCompleted:

static void ctl_ManipulationCompleted(object sender,
            ManipulationCompletedRoutedEventArgs e)
{
    var element = sender as FrameworkElement;
    ICommand command = null;

    // x < 0 --> verso sinistra
    // x > 0 --> verso destra
    var x = e.Cumulative.Translation.X;

    // y < 0 --> verso l'alto
    // y > 0 --> verso il basso
    var y = e.Cumulative.Translation.Y;

    if (y < 0 && Math.Abs(y) > Math.Abs(x))
    {
        command = GetUp(element);
    }
    else if (y > 0 && Math.Abs(y) > Math.Abs(x))
    {
        command = GetDown(element);
    }
    else if (x > 0 && Math.Abs(x) > Math.Abs(y))
    {
        command = GetRight(element);
    }
    else if (x < 0 && Math.Abs(x) > Math.Abs(y))
    {
        command = GetLeft(element);
    }

    if (command != null)
    {
        if (command.CanExecute(null))
        {
            command.Execute(null);
        }
    }
}

All’interno dell’evento posso capire quale tipo di gesture ha fatto l’utente sul controllo. Avendo impostato il ManipulationMode solamente alle traslazioni X e Y, sappiamo per forza di cose che arriveremo qui solo in presenza di questa gesture. Capisco la direzione del movimento seguendo due fattori:

  • il valore di x e y, ovviamente
  • quale dei due valori x e y ha più rilevanza l’uno con l’altro (spostando il dito verso l’alto, probabilmente lo sposterete anche a sinistra o a destra – grazie a Math.Abs() capisco quale asse ha avuto più rilevanza nella gesture)

I base alla direzione, ottengo l’ICommand associato. Ovviamente può anche essere null, nel caso in cui non abbia bindato alcun command. Se invece c’è, invoco il CanExecute, ed in caso di esito positivo, eseguo finalmente il comando associato.

Si potrebbe pensare di aggiungere il CommandParameter per ciascuna delle quattro direzioni, ma a me non serve, per cui lo lascio fare voi!

Il codice completo della classe pronta all’uso è qui. E’ stata scritta in circa 30 minuti, ci sarà sicuramente qualche bug: avvisatemi e correggiamola/miglioriamola insieme!

Send to Kindle
Community

Configurazione di Word 2013 con WordPress hostato su Winhost.com

Ho avuto qualche difficoltà a configurare Word 2013 per poter pubblicare i miei post sul mio blog. Nonostante il mio strumento preferito rimanga Windows Live Writer, ho tentato di dare una possibilità a Word perché ad oggi è l’unico software di blogging disponibile anche sotto Windows RT. La procedura è molto semplice; ciò nonostante ho avuto qualche difficoltà, non tanto perché avessi problemi intrinseci con Word 2013, quanto per il modo con cui ho configurato le cose server-side, e quindi sul mio hosting Winhost.

Piccola premessa.
Se si vuole attivare un dominio di terzo livello sul proprio dominio, è necessario procedere in due step:

  • Attivare il dominio (esempio: se state gestendo il dominio pippo.com e volete attivare admin.pippo.com, dovete per l’appunto attivare il sub-domain “admin”)
  • Creare un folder “admin” via ftp alla root
  • Impostare il meccanismo di url-rewrite in modo tale che quando viene intercettata una chiamata ad un url che cominci per “admin”, gli si dice di reindirizzare il tutto all’interno del folder “admin”

Come ben sapete, la mia esperienza con hosting, web, web.config, IIS e dintorni non è poi così tanta. Ma seguendo questi step sono riuscito, per esempio, ad attivare domini come “blog.vivendobyte.net”, “fsxlogger.vivendobyte.net”, “service.vivendobyte.net”, eccetera eccetera. L’unica pecca di tutto questo è che l’url-rewrite fa una cosa un po’ sporca, ovvero trasforma l’url “http://blog.vivendobyte.net<l’url continua>” in “http:// blog.vivendobyte.net/blog/<l’url continua>”. Insomma, rende evidente l’esistenza del folder “blog” nelle mie cartelle sul server.

Soluzione
Morale, per configurare Word 2013 per postare sul proprio blog bisogna indicare l’url comprensivo di sub-folder, ovvero:
http://subdomain.domain.net/folder/xmlrpc.php.

Non so se è anche il vostro caso, ma io ho risolto così. Ed adesso, blogging a tutta forza con Word 2013 anche su Windows RT.

Send to Kindle