Feb 10 / Igor Damiani

Visual Studio 2017 esce il prossimo 07/03

Beh, secondo questo post ufficiale Visual Studio 2017 uscirà ufficialmente il prossimo 7 marzo. Sarà un martedì. Quel giorno mi raccomando: scaldate i PC, riavviate i vostri modem per scaricare il più velocemente possibile i file iso per effettuare il setup.

Avrò occasione, qua sul mio blog ed in altre parte del web (ho delle sorprese in merito), di raccontarvi tutte le novità del nostro IDE. Vi parlerò di sviluppo di applicazioni desktop e di applicazioni UWP, di Azure, e di tanto altro ancora, come ormai è consuetudine.

Non mancate l’appuntamento!!!!

Send to Kindle
Feb 9 / Igor Damiani

[Ammy.5] Modifiche a runtime del codice

Il linguaggio Ammy supporta una feature a mio avviso straordinaria, anche se ad oggi presenta dei piccoli bug, già segnalati.

Mentre la vostra applicazione WPF è in running, potete tranquillamente continuare a lavorare sul codice della UI – scritta in Ammy – senza interromperne l’esecuzione.

Per farlo, il runtime di Ammy utilizza i socket. Ecco il motivo per cui la prima volta che fate F5 con Visual Studio il firewall di Windows intercetta la comunicazione di rete:

image

Ovviamente dovete cliccare su Consenti accesso. Fatto questo potete mantenere l’applicazione in esecuzione (magari su un monitor secondario), tornare in Visual Studio ed editare in tutta libertà il codice Ammy. Ogni volta che salverete il file, Visual Studio scatenerà un refresh della Window.

Sulla homepage ufficiale di Ammy c’è un bel video di poco meno di 30 minuti che vi mostra questa caratteristica del linguaggio. Cito testualmente dalla fonte: “Note that application was always running during the development, never needing to restart”.

Voglio farvi notare un’ultima cosa, prima di salutarvi. Nell’editor di codice Ammy c’è un pallino che indica la validità del codice Ammy (lo ricordo, che riprende la sintassi dal JSON). Quindi:

  • Pallino verde: tutto ok
  • Pallino rosso: qualcosa non va in Ammy

image

Personalmente, ad oggi trovo piuttosto ostico scrivere Ammy. Dopo 10 anni di XAML, è dura cambiare linguaggio per la UI, ma i vantaggi ci sono, cerco di adeguarmi, per cui butto sempre un occhio a questo indicatore per avere una conferma visiva. Per ora non sto usando Ammy in alcun progetto reale per un cliente, ma non si sa mai.

Ok! Mi hai detto che ci sono dei bug, quali sono?
I bug di Ammy sono tanti, essendo un linguaggio in fase di sviluppo. Per rimanere sul tema di questo post, accade la seguente cosa. Supponiamo di avere un po’ di code-behind, legato ad un evento di un qualsiasi controllo della UI. Ricordate la PasswordBox di cui abbiamo parlato nell’ultimo post? Supponiamo di sottoscriverne l’evento PasswordChanged.

PasswordBox {
#Cell(1, 1),
VerticalAlignment: Center,
HorizontalAlignment: Stretch,
PasswordChanged: "changed"
}

E’ esattamente come faremmo con lo XAML. L’intellisense ci viene in aiuto, fino ad un certo punto. Purtroppo dobbiamo scrivere noi l’event handler legato a questo evento. Una volta che avete sottoscritto l’evento e predisposto l’event handler nel code-behind, ovviamente tutto funziona. Fate per scrivere una password, e passate dal codice del vostro handler. Nulla di strano fino a qua.

Se successivamente modificate il codice Ammy a run-time e salvate, la Windows viene aggiornata, ma l’event handler si sgancia. Morale: dovete stoppare e riavviare l’applicazione. Da tener presente che tutto questo accade se lavorate con eventi ed un po’ di code-behind. Se approcciate con MVVM il problema non si pone, ma c’è comunque.

Happy coding!

Send to Kindle
Feb 8 / Igor Damiani

Formattazione XML con Notepad++

Negli ultimi giorni ho litigato parecchio con Open XML SDK, la libreria Microsoft open che permette di creare da codice documenti di tipo Office, vale a dire Word ed Excel, giusto per citarne i due più famosi.

E’ giusto ricordare che i formati .docx e .xlsx non sono nient’altro che file zip compressi, che al loro interno contengono tutte le informazioni per rappresentare i documenti. Ed il tutto è gestito attraverso file XML che possono essere tranquillamente letti, modificati e manipolati. La libreria Open XML SDK semplifica un po’ le cose, ma c’è comunque da impazzire un pochino.

Fatta questa premessa, mi è capitato di dover visualizzare questi file XML attraverso Notepad++ che, purtroppo, di default non è in grado di formattare a dovere. Quindi, per riassumere:

  • apro un file .docx attraverso 7-Zip
  • navigo i folder contenuti, seleziono un file XML
  • premo F4 per avviare l’editor, nel mio caso Notepad++
  • il file XML è visualizzato su una singola lunghissima linea di codice.

Burp! Panico.

Come risolvere? Con i plugin giusti di Notepad++, ovviamente.

  • Aprite Notepad++
  • Aprite il menù Plugins –> Plugin Manager –> Show Plugin Manager

image

Dall’elenco dei plugin selezionate XML Tools.

image

Cliccate Install, riavviate Notepad++. Purtroppo potrebbe capitarvi di dover riavviare un paio di volte Notepad++, perchè prima vi aggiorna il Plugin Manager e poi dovete richiedere nuovamente l’installazione del plugin XML Tools. Fatto questo, avete abilitato tutta una serie di nuovi strumenti per lavorare più velocemente con i file XML.

image

Et voilà, un bel colpo di Pretty print per formattare l’XML e poterlo leggere comodamente!

Send to Kindle
Feb 7 / Igor Damiani

[Ammy.4] Fare binding con Ammy

Nel post precedente abbiamo mosso i primi passi con WPF & MVVM sviluppato con Ammy. Abbiamo creato una view ed abbiamo visto come legare staticamente questa view con il suo viewmodel.

Ricordo che tutto il codice sorgente si trova su GitHub:
https://github.com/Brain-Sys/FsxLogger.Client

Adesso, come facciamo binding?

L’unica view con cui abbiamo a che fare è contenuta nel file LoginWindow.ammy. La UI è questa:

image

Un controllo TextBox ed un PasswordBox, seguiti poi da due Button per eseguire due comandi (uno effettua il login e l’altro annulla l’operazione, per cui l’applicazione WPF viene chiusa).

La TextBox è collegata alla proprietà Username del ViewModel.

TextBox {
#Cell(0, 1),
VerticalAlignment: Center,
HorizontalAlignment: Stretch,
Text: bind Username,
Padding:"4" }

Notare l’uso del mixin Cell. La penultima riga effettua il binding. La sintassi è molto compatta.

Text : bind Username

Abbiamo utilizzato la keyword bind di Ammy. La proprietà del viewmodel va indicata senza virgolette né apici, semplicemente indicando il nome della proprietà, come faremmo con lo XAML.

Se dovessimo impostare ulteriori proprietà per fare il binding (Mode, UpdateSourceTrigger, StringFormat, NotifyOn*), allora la sintassi cambia leggermente. Si ragiona sempre in JSON:

Text: bind Username set
[
Mode: TwoWay,
UpdateSourceTrigger: PropertyChanged,
IsAsync: true
]

Dopo il Set si indica un array di proprietà, ciascuna con il suo valore. Nel caso specifico, impostare Mode ed IsAsync non era necessario, l’ho fatto a solo scopo didattico.

Per quanto riguarda i due Button, il binding verso i Command è semplicemente espresso come:

Button { Content: "Login", Command: bind LoginCommand }
Button { Content: "Cancel", Command: bind CancelLoginCommand }

Ovviamente LoginCommand e CancelLoginCommand sono due proprietà RelayCommand (stiamo utilizzando MvvmLightLibs) esposte dal viewmodel. Cliccando su ciascuno dei due bottoni, viene scatenato il Command corrispondente. Non ci interessa approfondire altro in questo contesto.

Risolvere il problema del binding sul controllo PasswordBox è un po’ più complicato, perchè la proprietà Password non è una DependencyProperty. E’ OT rispetto a questo post, ma lo risolveremo.

Altri tipi di binding

Vediamo adesso altre forme di binding. Parliamo di come poter impostare il focus sul primo controllo all’avvio della finestra, posizionandolo sul controllo PasswordBox.

Questa cosa si risolve con due passaggi:

  1. diamo un nome al controllo a cui vogliamo assegnare il focus
  2. utilizziamo la classe FocusManager

Risolviamo prima lo step (1).

PasswordBox {
#Cell(1, 1),
VerticalAlignment: Center,
HorizontalAlignment: Stretch,
Name: "focus" }

Il nome assegnato al controllo è focus. A questo punto andiamo ad utilizzare la seguente sintassi associata alla Window.

FocusManager.FocusedElement: bind from "focus"

Utilizziamo la keyword bind seguita da from, che ci permette di cambiare il Source dell’oggetto verso il quale stiamo effettuando il binding. La stringa successiva “focus” rappresenta il nome del controllo. Lo XAML generato dal codice Ammy qui sopra è il seguente:

<FocusManager.FocusedElement>
<Binding ElementName="focus"/>
</FocusManager.FocusedElement>

Sostanzialmente, quando utilizziamo la sintassi bind from seguito da una stringa tra virgolette, questa stringa viene considerata come ElementName, quindi il Source diventerà un controllo WPF.

Da adesso in poi, quando la Window verrà renderizzata sullo schermo, WPF assegnerà il focus automaticamente al controllo PasswordBox: l’utente potrà premere Invio e fare login.

Beh, cosa posso indicare dopo il “from” ?

Ammy permette di scrivere binding di questo tipo:

  • bind Username from $viewmodel (comportamento predefinito, al punto che è possibile omettere from $viewmodel)
  • bind XYZ from $this, equivalente a RelativeSource={RelativeSource Self}
  • bind from $resource XYZ, equivalente a Source={StaticResource XYZ}

Per maggiori dettagli fate riferimento al sito ufficiale di Ammy.

Happy coding!

Send to Kindle
Feb 6 / Igor Damiani

Montaggio video con ffmpeg

Nei mesi scorsi, quando ero in ballo con il progetto DevInPills, mi è capitato di dover montare tre video, concatenandoli uno all’altro, sostanzialmente per ottenere una cosa tipo:

SIGLA DI APERTURA + EPISODIO DEL GIORNO + SIGLA DI CHIUSURA

Ho evitato di cercare un software tradizionale, ma ho preferito puntare su uno strumento che fosse automatizzabile. Leggesi, quindi, da eseguire anche dal prompt dei comandi.

Ho puntato quindi sull’utility ffmpeg che, come dichiara il sito ufficiale, è un “complete, cross-platform solution to record, convert and stream audio and video”. Dalla linea di comandi potete insomma eseguire tantissime operazioni, e come potete immaginare io ne ho imparato una minima parte, quelle che avevo bisogno per finire ciò che mi serviva.

Beh, allora, come si fa?
Supponiamo di avere un folder così composto:

image

  • ffmpeg.exe : è portable, non va installato, basta posizionare l’exe da quasi 40Mb dove vi serve. Comodo.
  • In.mp4 : video di apertura del video finale
  • Out.mp4 : video di chiusura del video finale
  • Produce.ps1 : script Powershell che effettua il montaggio del video

Quello che manca nella cartella qui sopra è “Episode.mp4”, supponiamo che ci sia, e pensiamo ad esso come se fosse la nostra puntata.

Cosa contiene lo script Powershell? E’ semplice!

$InputFile = "Episode.mp4"

#--------------------------------------
#Please don't touch these values
#--------------------------------------
$ExePath = ".\ffmpeg.exe"
$OpeningFile = "In.mp4"
$EndingFile = "Out.mp4"
$FinalFile = "FINAL_" + $InputFile
#--------------------------------------

# Concatenate "In.mp4" + $InputFile + "Out.mp4"
# Save the result in $FinalFile
& $ExePath -i $OpeningFile -i $InputFile -i $EndingFile -filter_complex '[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]' -map "[v]" -map "[a]" $FinalFile

Ci sono un po’ di variabile definite nello script.

  • $InputFile : è il nome del file che contiene il nostro episodio
  • $ExePath : path dove recuperare ffmpeg.exe
  • $OpeningFile : video di apertura
  • $EndingFile : video di chiusura
  • $FinalFile : nome del file video finale che verrà generato (uso come prefisso “FINAL_” rispetto al nome del file contenuto in $InputFile)

L’ultima linea esegue ffmpeg e procede al concatenamento dei tre video, che come si vede dal commento è un banale “In.mp4” + “Episode.mp4” + “Out.mp4”. La sintassi è alquanto criptica, devo dire. Ovviamente ho cercato la soluzione e poi l’ho adattata ai miei scopi.

Secondo me, se gestite un sito di video (su Facebook, YouTube, etc.) o magari una community che intende pubblicare frequentemente dei video, è uno script più che utile, perchè vi permette di registrare la vostra puntata sotto forma di Episode.mp4, copiare il file nella cartella giusta, lanciare lo script ed in pochi minuti ottenete il video montato, con la sigla di apertura & chiusura.

ffmpeg fa tantissime altre cose (cambio di risoluzioni o di aspect-ratio di un video, cambiamento del bitrate per diminuire la qualità ed ottenere un file più compatto), etc. Googlate e carpite la sintassi che serve ai vostri scopi.

Send to Kindle
Feb 3 / Igor Damiani

[Ammy.3] Primi passi con MVVM

Come ho raccontato nel mio ultimo post dedicato a questa serie, preferisco continuare a raccontarvi il linguaggio Ammy usando un progetto il più possibile reale, motivo per cui ho creato questo repository sull’account GitHub di Brain-Sys, che potete tranquillamente clonarvi sul vostro PC:

https://github.com/Brain-Sys/FsxLogger.Client

Allo stato attuale, la solution che vi ritroverete sul PC è così composta:

image

Tralasciamo per ora lo scopo preciso della nostra applicazione WPF. I progetti sono quattro:

  • FsxLogger.Client : l’applicazione WPF sviluppata con Ammy
  • FsxLogger.ViewModels.Portable : una serie di viewmodel implementati in PCL
  • FsxLogger.ViewModels.Wpf : una serie di viewmodel che ereditano da quelli PCL, ma si specializzano per il mondo WPF
  • FsxLogger.ViewModels.Message : messaggi da utilizzare per far comunicare viewmodel con l’applicazione WPF, utilizzando la classe Messenger di MvvmLightLibs

Detto questo, parto dal presupposto che conosciate WPF, C#, MVVM, il motore di binding di WPF, e la solita serie di nozioni che è necessario avere. Andiamo per gradi.

Prima di partire in quarta…qualche nozione introduttiva
La nostra applicazione WPF ha una finestra di Login per l’autenticazione, che ovviamente è la prima che compare quando l’applicazione parte. Essa si chiama, con molta fantasia, LoginWindow.ammy. E’ questa la prima finestra che andremo a sviluppare. Il corrispondente viewmodel si chiama LoginViewModel, e si trova nell’assembly PCL.

image

Importare un namespace
La prima necessità che abbiamo è quella di importare un namespace in linguaggio Ammy, esattamente come faremmo con lo XAML, né più né meno. La sintassi è molto semplice, perchè basta utilizzare la keyword using, che è la stessa che useremmo con C#. Dopo aver aggiunto le reference (dal progetto FsxLogger.Client ho aggiunte le reference agli altri 3, per capirci), possiamo prendere un file .ammy ed all’inizio dichiarare il namespace in questo modo:

using FsxLogger.ViewModels.Portable

Da questo momento in poi, l’Intellisense reagirà e potremo inserire le classi contenute in quel namespace. Nelle risorse della Window inseriamo il viewmodel.

Resources: [
LoginViewModel Key="vm" { }
]

Questa è la sintassi da utilizzare. La proprietà Resources delle Windows è di tipo ResourceCollection, quindi può contenere ovviamente più oggetti, motivo per il quale abbiamo dovuto usare le parentesi [ e ], come in JSON, per indicare un array di oggetti. All’interno ho inserito la classe LoginViewModel (notare: senza usare alcun prefisso come invece accadrebbe in XAML), assegnando una Key “vm”. Fatto.

Passo successivo è quello di assegnare la proprietà DataContext ad un controllo (la finestra? il controllo più esterno del visual tree?) per far propagare il viewmodel per tutta la view.

Nel mio caso, ho impostato DataContext sulla Grid a linea 14.

Grid
{
DataContext: resource "vm",
#TwoColumns(120), #ThreeRows("Auto", "Auto"),
Margin: "8"
}

Il codice che vedete qui è semplificato rispetto a ciò che vedete su GitHub. Notare l’utilizzo della keyword Ammy resource, equivalente alla StaticResource di XAML, ma lievemente più compatta.

Come accade con lo XAML, il DataContext fa propagare la classe di viewmodel per tutto il visual tree della nostra UI. Grazie a questo meccanismo, da qui in avanti potremo fare binding sui controlli e rendere il tutto funzionante. Ma questo è argomento dei prossimi post.

Prima di chiudere, due note importanti

Ricordiamoci sempre che compito di Ammy è quello di generare l’equivalente codice XAML. Ciò significa che mentre noi lavoriamo sulla view LoginWindow.ammy, da qualche parte esiste un altro file LoginWindow con estensione XAML. Dove si trova? E’ semplice: nel solution explorer attivate l’opzione “Show All Files”, così cominciate a vedere anche quelli nascosti. Eccolo lì, l’avete trovato!!!

image

E’ molto comodo perchè questo file XAML è autogenerato dal codice Ammy, e quindi potete man mano verificare che tutto funzioni regolarmente.

E perchè, allora, usare Ammy? Lo ripeto: perchè è estremamente più compatto, perchè ci sono mixin ed alias (utilissimi), perchè fare binding con la sintassi XAML è più veloce e parlante (Intellisense permettendo), per i bellissimi inline binding converter, che sono meravigliosi.

La seconda ed ultima cosa che vi voglio far notare è che Ammy non si lamenta se per sbaglio specificate due volte la stessa proprietà sullo stesso controllo, cosa che invece XAML fa. Mi spiego meglio; guardate questo stralcio di codice:

Window "FsxLogger.Client.LoginWindow"
{
Width: 320, Height: 240, Width: 320, Height: 240
WindowStartupLocation: CenterScreen,
WindowStyle: ToolWindow, Title: "Login"
FocusManager.FocusedElement: bind from "focus"
}

Ho ripetuto Width e Height della Window due volte, volutamente, per sbaglio. Ammy non si lamenta. XAML lo farebbe, invece. Andate a dare un’occhiata al codice XAML generato. Ammy fa una cosa molto semplice: evita di duplicare quelle proprietà, esattamente come dovrebbe fare.

Il codice compila, l’applicazione parte, noi siamo felici.

Alla prossima! Happy coding!

Send to Kindle
Feb 2 / Igor Damiani

Scusi, mi rifà il programma?

Questo post è basato su fatti realmente accaduti.

E’ successo. E’ ricapitato. Per l’ennesima volta, è riaccaduta la stessa cosa.

Un potenziale cliente vi contatta, vi incontrate, chiaccherate per la prima volta su quello che dovrà fare il meraviglioso software che ha in testa. E per l’ennesima volta devi ricostruire, riprogettare da zero, un software già esistente, scritto lustri prima in MFC, o in Visual Basic 4.0, o in Access 97 o addirittura 2.0. E chiamano te per riconvertirlo e riprogettarlo in .NET, magari perchè si sono accorti che non sono più competitivi sul mercato, perchè il codice è diventato ingestibile, perchè vogliono avere l’app sotto iOS o Android, o per mille altri motivi. Non c’è documentazione, c’è solo un gruppetto di persone che sanno perfettamente cosa deve fare il software, ma non c’è nulla di scritto e di formalizzato. Non c’è nulla di male in tutto questo, d’altronde lavoro è lavoro.

Tu, con il tuo bravo e fidato Visual Studio, vorresti cominciare lo sviluppo di questo software magari con DDD, scrivendo le classi e pensando accuratamente il dominio applicativo, quindi – per farla breve – approcciando ad una metodologia code-first. Prima le classi, in seguito la logica, poi penserai al modello di persistenza. Ma il tuo cliente ragiona diversamente; come accadeva decenni fa (quando il suo software è stato scritto la prima volta) ragiona partendo dal database. Per lui è essenziale vedere lo schema del database, per capire se stai scrivendo la cosa giusta. Prima di vedere anche una sola linea di codice C#, vuole vedere le tabelle, le relazioni, i campi ed i nomi dei campi come piacciono a lui.

Di fronte ad una situazione di questo tipo, ci sono tante strade. Ne cito due.

  1. Tu ragioni sempre e comunque code-first. Scrivi le classi e lasci che sia l’ORM (Entity Framework?) a generarti tutto il mondo della persistenza relazionale. Ma siccome per il cliente lo schema del database è fondamentale – dal quale dipende il Supremo Destino della nostra Galassia – allora cominci a litigare con attributi o con vagonate di codice, per educare l’ORM a generarti lo schema del db esattamente come lo vuole il cliente
  2. Ti arrendi all’evidenza e cominci a progettare il database. Quindi segui il modello database-first. Fattibile, no? Al massimo, parlando di Entity Framework, una volta creato il database puoi farti comunque generare le classi tramite l’approccio “Code First from database”. Così al massimo puoi attivarti le migration…

image

Il discorso, a mio avviso è semplice. Se vuoi portare a casa la pagnotta, al cliente devi comunque dare retta. Se il tuo committente, magari perchè è stato educato male, ragiona partendo dal database, purtroppo non puoi farci nulla. Io poi parto da un semplice presupposto: se hai chiamato me, non vuoi semplicemente uno che digita o scrive codice, ma vuoi uno che ci metta la testa. Però non sempre si ha questa possibilità, per diversi motivi.

Detto questo, il primo approccio è code-first solo in apparenza. Tecnicamente cominci scrivendo un sacco di classi, ma in realtà nella tua testa sei costantemente traviato da ciò che dovrai ottenere come struttura sul database. E’ solo un palliativo, insomma. Scrivi una classe, e poi via…tonnellate di codice nel metodo OnModelCreating di Entity Framework per piegare ai tuoi voleri l’ORM. Burp, equivalente al ruttino.

Il secondo approccio è a tutti gli effetti database-first. E se il cliente ragiona in questo modo, che male c’è? Siamo pagati per scrivere un software o per fare gli accademici? Quindi, che male c’è ad aprire il Microsoft SQL Server Management Studio, stendere tutte le tabelle, campi, relazioni, e poi importarle via Entity Framework? In questo modo il cliente è soddisfatto, io ho le mie classi su cui poi cominciare a sviluppare. Se il progetto è di una certa importanza e/o durata, ci sarà magari tutto il tempo per guadagnare stima e fiducia verso il cliente, e ci saranno tutte le occasioni per indirizzarlo verso strade e percorsi più moderni allo sviluppo del software.

Send to Kindle
Feb 1 / Igor Damiani

Riportare in vita Microsoft Money?

Non so quanti di voi miei lettori lo abbiano utilizzato in passato. Microsoft Money è un bel software di produttività personale, per tener traccia delle proprie spese, di tenere sotto controllo il proprio budget, dotato (secondo me) di un’interfaccia utente pulita, colorata ed accattivante.

Money è stato dismesso da parecchi anni. Ma ieri, 30 gennaio, è stata avviata una raccolta di firme, una petizione insomma, per riportarlo in vita e farlo rientrare nella ben nota suite Microsoft Office. La petizione è rivolta a niente meno che Satya Nadella. E sono richieste anche feature innovative, come una versione per dispositivi mobili, o la possibilità di averne una versione Web integrata con Office 365. Sarebbe davvero una cosa molto molto interessante.

Nel momento in cui vi scrivo mancano 300 firme al raggiungimento delle 1.000 necessarie all’invio di tutte le firme a Sua Maestà Nadella. Chissà se qualcuno ci farà un pensierino.

Trovate maggiori informazioni qua:
https://www.change.org/p/satya-nadella-bring-back-microsoft-money-as-part-of-microsoft-office

Beh, che ne dite? Si può fare? Ci state?

Send to Kindle
Gen 31 / Igor Damiani

Uso Trello, e non ne faccio più a meno

Dall’estate scorsa utilizzo Trello, e ve ne voglio parlare.

Lo trovo utile per tenere traccia delle mie attività, non solo lavorative.

L’organizzazione avviene tramite Bacheche, che di default è privata, mentre può essere condivisa con altre persone, feature tra l’altro che non ho ancora provato con una certa continuità. Ciascuna Bacheca può contenere una o più Liste, ogni Lista può contenere una o più Schede. Queste ultime contengono le vere attività di lavoro, che possono essere espresse in diversi modi: semplici appunti e check-list da completare, per esempio. Ogni scheda può avere una data di scadenza, allegati, e via dicendo.

Ad oggi, le Bacheche che utilizzo sono fondamentalmente tre:

  • Attività personali
  • Brain-Sys
  • Piloti Virtuali Italiani

image

Ne ho nascosta una per motivi di privacy.

All’interno di Attività personali ho istanziato due schede: Attività Social ed Altro. Nelle Attività Social creo una scheda ogni volta che mi viene in mente un contenuto di cui parlare qua sul mio blog, mentre in Altro mi segno un po’ tutto il resto: ricordarsi di cercare un’assicurazione RCA più conveniente di quello che ho adesso, lista della spesa, ricordarsi di comprare questo o quello, etc.

Per quanto riguarda la Bacheca dedicata a Brain-Sys, ho una scheda per ciascun cliente che gestisco. E per ogni cliente mantengo una lista delle attività in corso, ovviamente sotto forma di appunti rapidi e veloci, perchè l’analisi, gli use-case e la documentazione di progetto sta da tutt’altra parte. Però…sapete…quelle attività estemporanee del tipo: ricordati di mandare la mail, scrivi il rapportino del giorno XYZ, fai due presale, rispondi a Silvia su questo & quello. Quelle attività difficilmente tracciabili in altra maniera.

La Bacheca di Piloti Virtuali Italiani è un po’ in disuso, o comunque meno attive delle altre due. Mi segno di rispondere via mail al socio, mi segno i Direttivi ai quali devo partecipare, etc.

Ad una Bacheca possiamo impostare un colore di sfondo, possiamo installare dei plug-in (chiamati Power-Up) per abilitare funzioni avanzate, possiamo consultare velocemente la history di tutte le modifiche apportare, etc. Tutto molto veloce ed a portata di click.

Alcune feature interessanti delle schede
Ogni scheda ha caratteristiche interessanti. Come dicevo prima, ogni scheda rappresenta un’attività da portare a termine. Possiamo associargli una eventuale etichetta (che determina il colore con la quale verrà rappresentata sullo schermo), una data di scadenza. Ogni scheda è composta da uno o più commenti, che possono essere testo, indirizzi web, etc. In una scheda possiamo inserire una check-list: ve ne parlo più sotto. All’interno di un testo possiamo menzionare un membro con il quale stiamo condividendo i contenuti. Possiamo allegare uno o più file in allegato, di qualsiasi tipo.

Ogni elemento di Trello (Bacheca, Scheda, Lista) può essere archiviato: questo significa che non viene più visualizzato sullo schermo. Ovviamente possiamo sempre recuperarlo in futuro, nel caso in cui ci servisse recuperare qualcosa.

L’interfaccia web è gradevole, pulita, essenziale e risponde bene. Sapete quanto io preferisca, normalmente, le applicazioni desktop o mobile rispetto ad un’applicazione usufruita via browser. Beh, non è questo il caso.

Shortcut tramite tastiera
Una feature interessante è la presenza delle scorciatoie da tastiera, che permettono di avviare subito operazioni veloci. Premete “d” mentre siete su una scheda per impostare la data di scadenza, per esempio. Premete i tasti numerici per associare subito un’etichetta, e così via. Fantastico. Potete vedere o disattivare gli shortcut dal menù di opzioni in alto a destra.

Il punto di forza…sono due…!!!!!
Il primo è, secondo me, la flessibilità di ogni scheda, che consente di prendere appunti in modo libero, impostare una eventuale data di scadenza, allegare file in allegato di qualunque tipo. La feature che mi piace di più è la possibilità di creare le cosiddette check-list, ovvero un elenco di task da portare a termine. Trello evidenzia con una sorta di barra di progresso lo stato di quella check-list, così che avete con un colpo d’occhio la situazione di ciò che dovete fare, quanto e cosa vi manca alla fine, etc.

Ma allo stesso tempo è rigido, nel senso che tutto è ben strutturato e suddiviso in Bacheche, Lista e Schede, e non potete sfuggire – giustamente – da questa struttura generale. OneNote per certi versi è un prodotto paragonabile a Trello, ma quest’ultimo è più improntato alla gestione degli appunti, agli sketch, ad un testo comunque più lungo e complesso. Passatemi il paragone: Trello è il Twitter dei Task Manager. Vi suggerisce di essere concisi, rapidi ed essenziali. Eppure ha tutto.

L’altro punto di forza è la presenza delle app, che vi permettono di aprire, consultare e gestire il vostro Trello da Android o iOS. Onestamente in questo momento, mentre vi sto scrivendo, non sono in grado di garantirvi la presenza di app per Windows 10. Io ho installato l’app per Android, mi trovo più che bene e vi posso assicurare, per quello che vale, che vi capiterà spesso di aprirla per leggere o scrivere qualcosa. O forse dipende da me, dal fatto che ultimamente ho il cervello in fermento!

E non ne faccio più a meno
Non ne faccio più a meno, perchè grazie a Trello riesco a mettere in fila le cose che devo fare, e che altrimenti mi sfuggirebbero. Grazie a Trello ho ricominciato a scrivere sul blog, perchè ogni volta che mi si accende la lampadina su un eventuale contenuto, me lo segno…e la sera, quando mi metto davanti al PC a scrivere, pesco a caso da ciò che mi ero appuntato.

Se come me siete un po’ distratti, tendete a dimenticare le cose o volete semplicemente essere più organizzati, date una possibilità a Trello. Per me è diventato uno strumento essenziale.

Send to Kindle
Gen 30 / Igor Damiani

[Ammy.2] Il file lib.ammy: mixin e alias

Quando in un progetto WPF installate tramite NuGet la libreria Ammy, nel progetto vi ritrovate anche un file lib.ammy. Cosa contiene? A cosa serve?

Il file lib.ammy contiene tantissime funzioni utilissime e pronte all’uso.
Tali funzioni in linguaggio Ammy sono divise in due tipologie:

  • Mixin
  • Alias

Il file lib.ammy è liberamente modificabile, e quindi possiamo aggiungere nostri mixin o alias, oltre che ovviamente modificare o migliorare quelli esistenti.

Utilizzare i mixin
Concettualmente parlando, un mixin assomiglia ad un tradizionale stile di WPF. Un mixin si applica ad un controllo WPF – come uno stile – e restituisce un set di proprietà ben definito. Ad esempio:

mixin Header() for TextBlock {
FontWeight: Bold,
FontSize: 36,
Foreground: DarkGray
}

Questo stralcio di Ammy definisce un mixin chiamato Header, che è applicabile a tutte le TextBlock, a che in pratica definisce dei valori per le proprietà FontWeight, FontSize e Foregound. Come si utilizza? In questo modo:

Window "StudyAmmy.StartWindow" {
StackPanel { Orientation: Horizontal,
Children: [
TextBlock { Text: "some text", #Header() }
] }
}

Nel momento in cui si inserisce un controllo per cui esiste un mixin, esso diventa disponibile nell’Intellisense. Quindi, inseriamo una TextBlock, valorizziamo la proprietà Text e poi richiamiamo il mixin che ci interessa con la sintassi #Header(). Il mixin inietta le sue proprietà all’interno del JSON. Notare la sintassi con le parentesi () che ricorda il fatto che stiamo chiamando una funzione.

Sembra uno stile, vero? Peccato che i mixin siano decisamente più potenti rispetto ad uno Style di WPF, banalmente perchè si possono applicare anche su quelle proprietà che uno Style non raggiunge.

Ad esempio:

mixin TwoColumns (one = "*", two = "*") for Grid {
combine ColumnDefinitions: [
ColumnDefinition { Width: $one }
ColumnDefinition { Width: $two }
]
}

Questo mixin chiamato TwoColumns, che fa parte di quelli definiti nel file lib.ammy, permette di definire velocemente una Grid con due sole colonne:

image

Ad esempio, si potrebbe scrivere questo codice:

Grid
{
#TwoColumns("*", "2*"),

Background: LightGray,
Margin: 4,
ShowGridLines: true,
TextBlock { Grid.Column: 0, Text: "1° colonna",
FontSize: 24, Margin: 4 },
TextBlock { Grid.Column: 1, Text: "2° colonna",
FontSize: 24, Margin: 4 }
}

Per ottenere una UI di questo tipo:

image

Notare che i mixin possono avere parametri in input. Il mixin Header non ne aveva, mentre TwoColumns ne aveva due, grazie ai quali è possibile specificare la larghezza delle due colonne. I parametri possono avere valori predefiniti, come è possibile fare con C#.

Ricordiamoci che per richiamare un mixin è necessario utilizzare il carattere #.

Se stiamo scrivendo un mixin e vogliamo utilizzare uno dei parametri in input dobbiamo usare $.

Utilizzare gli alias

Scopo degli alias è quello di generare un oggetto, come un controllo, ma in generale un qualsiasi oggetto inseribile con lo XAML. Mentre un mixin ha un nome, si collega ad un controllo e produce in output un set di proprietà, compito dell’alias è quello di produrre in output un oggetto vero e proprio. Per esempio:

alias ButtonWithPadding(text, padding) {
Button { Content: $text, Padding: $padding }
}

Questo blocco Ammy definisce un alias che, quando chiamato, produrrà in output un controllo Button. L’alias ha due parametri di input – text e padding – che vi permetterà di inserire nella UI un button con quelle caratteristiche, in modo molto più compatto rispetto a quello che avremmo dovuto fare con XAML o senza usare l’alias.

Se leggete il file lib.ammy, troverete un gran numero di alias pronti all’uso, molto compatti, relativi per esempio a Trigger ed animazioni. Ad esempio, questo è molto interessante:

alias DoubleAnimation(
property,
frm = "0",
to = "1",
duration = "0:0:1",
targetName=none,
beginTime=none) {
DoubleAnimation {
Storyboard.TargetProperty: $property
Storyboard.TargetName: $targetName
From: $frm
To: $to
Duration: $duration
BeginTime: $beginTime
}
}

Ho calcato la mano con qualche “a capo” per rendere il codice più leggibile. Con una sola chiamata a questo alias, possiamo inserire una DoubleAnimation, passando in input il nome della proprietà, il valore iniziale e finale, la durata, etc. In modo estremamente compatto.

Sviluppiamo un progetto vero con MVVM?

Smettiamola di parlare di Ammy solo dal punto di vista puramente teorico. Dalla prossima volta implementeremo qualcosa con WPF e Mvvm, il pattern architetturale più adatto quando ci troviamo in un mondo basato su XAML. Vedremo come fare binding e come sfruttare le feature più interessanti di Ammy per essere più produttivi.

Happy coding!

Send to Kindle