Visual Studio 15.8 alla ricerca della parentesi graffa (chiusa) mancante

Se dopo l’installazione della versione 15.8 di Visual Studio 2017 avete problemi ad inserire nel codice la parentesi graffa chiusa (“}”), effettivamente c’è un bug, del quale fortunatamente esiste già un workaround. Seguite questi passaggi:

  • Aprite Visual Studio 2017
  • Andate nel menù Tools –> Options
  • Andate nella sezione Envinronment –> Keyboard
  • Nella casella di ricerca indicata da “Show commands containing” digitate “Edit.ExpandSelectiontoContainingBlock”
  • Vedrete che c’è la combinazione di tasti Ctrl+Shift+Alt+=
  • Cliccate sul pulsante Remove e confermate su OK per chiudere la finestra di dialogo

Et voilà, il problema è risolto. Ovviamente ci si attende che Microsoft risolva questa piccola svista con i prossimi rilasci.

Un ringraziamento a questi due tweet di Matteo Pagani e di Alessio Iafrate, che mi hanno permesso di trovare la soluzione.

Send to Kindle

Il silenzio sui social

Ci sono regole non scritte grazie alle quali il mondo si regge. Sono le regole del buonsenso. Ma affinchè queste regole continuino a funzionare, è necessario che esse vengano costantemente rispettate e seguite da tutti. E’ sufficiente che una sola persona evada da questa visione per far saltare gli schemi. Immaginate un autista contromano, oppure qualcuno che continua a suonare all’impazzata i citofoni della palazzina dove vivete, volumi delle radio e delle TV al massimo livello, uno che salta la fila alle poste, e così via. Sarebbe l’anarchia, no?

Una di queste regole è quella che riguarda il silenzio sui social. E’ di pochi giorni fa il dramma che ha colpito la città di Genova, con il crollo del ponte Morandi, che ha purtroppo causato la morte di decine di persone, con feriti, sfollati, eccetera eccetera. Sui social ovviamente si è scatenata la bagarre, a torto o a ragione. Discussioni infinite sulle cause, su chi doveva intervenire, sui selfie dei vari personaggi politici che hanno partecipato ai funerali di stato, sugli allarmi inascoltati lanciati negli anni precedenti, sui fischi a quelli del PD & sugli applausi a quelli dell’attuale maggioranza. E, si sa, come sempre sui social ogni cosa è amplificata ed esasperata.

Ho visto anche qualche amico invocare un po’ di silenzio, nel segno del rispetto verso chi ha perso la vita e verso i loro familiari. Io personalmente sono anche d’accordo, ma come dicevo all’inizio, è necessario che questo silenzio sia rispettato da tutti, altrimenti il meccanismo non sta in piedi, ma proprio per niente. Non trovo corretto aprire il proprio profilo Facebook e vedere un elenco infinito di post e condivisioni che rappresentano solo una parte dell’opinione pubblica, a maggior ragione che non rappresenta il mio. Secondo me, stiamo vivendo un’epoca nella quale ciascuna deve fare la sua parte, esprimendo la propria idea ed opinione. Per dirla diversamente: immaginatevi di aprire Facebook e di trovare un elenco spropositato di sciocchezze e fake news (alcune oggettive, altre meno). Come reagireste? Non vi verrebbe voglia di gridare la vostra verità? Credo proprio di sì. Anche perchè il risultato di un eventuale vostro non agire, sarebbe ancora più disastroso: tutte le notizie che circolano sui social sarebbero di parte, non vi rappresentano. Dal mio punto di vista è come leggere continuamente che 1+1 fa 3. No, c’è qualcosa che non va.

Tra l’altro, ritengo che il silenzio sui social per certi versi non debba esistere. D’altronde, nei bar e nei luoghi pubblici le persone hanno sempre parlato tra di loro, anche di fronte a fatti di cronaca, per cui perchè questo non deve avvenire anche sui social? Semmai la cosa difficile è parlarsi e confrontarsi con educazione, garbo e rispetto l’uno dell’altro. Purtroppo i social ad oggi banalizzano molto il dialogo (per la serie: se non sei con me, allora sei contro di me), e lo rendono aspro, duro e violento. Chissà, magari un giorno questo atteggiamento svanirà, ma è molto più probabile che i social così come li conosciamo oggi spariranno, soppiantati da altre forme di comunicazione digitali.

Send to Kindle

L’importanza dei tempi morti

Partiamo da un semplice presupposto: noi umani non siamo macchine pensate per produrre solo ed esclusivamente profitto, e non siamo stati progettati per avere una availability lavorativa del 99,99%. Per vivere bene, a lungo ed in salute abbiamo bisogno dei nostri tempi morti, che vengono scioccamente chiamati così ma che invece non lo sono affatto, almeno per quanto mi riguarda. La notte, durante il sonno, noi non facciamo nulla di cosciente, ma il nostro cervello lavora comunque ed ha bisogno di farlo, e si occupa di attività che non potrebbe svolgere durante il giorno. Il sogno è una fra queste, ad esempio. E, credetemi, sognare serve.

Per questa ragione, mi preoccupa un po’ sentire parlare amici e colleghi di come diminuire i tempi morti nelle proprie giornate, allo scopo di ritagliare tempo per il lavoro. Oggi si sta cavalcando moltissimo l’idea della macchina che guida da sola, e tantissimi (giustamente?) non vedono l’ora che diventi realtà. “Sai quanto tempo potremmo guadagnare ogni giorno?”, “Sai quanto tempo passo in coda per andare al lavoro?”. Certo, ovviamente, ovvio che in queste circostanze l’auto a guida autonoma potrebbe tornare utile. Ma mi dà terribilmente fastidio vedere come ci siano persone disposte a tutto pur di guadagnare tempo. Fidatevi: il tempo non basta mai, se riempiamo troppo le nostre giornate. Sarebbe una continua rincorsa. Non per niente a volte si afferma di aver bisogno di giornate da 48 ore. In futuro qualcuno potrebbe proporre di non dormire così tanto, o che mangiare come facciamo oggi è del tutto inutile (potremmo ingoiare una pillola in 15 secondi con tutte le sostanze che abbiamo bisogno), etc. etc. Passare del tempo bloccati in auto è ovvio che è una perdita di tempo, ma sarebbe una perdita di tempo anche un serata in pessima compagnia o un pranzo indigesto; la soluzione ad un pranzo indigesto non è evitare di mangiare, ma è mangiare meglio. La soluzione ad un viaggio in auto andato storto non è evitare di guidare facendolo fare ad una macchina o ad un software, ma è guidare in condizioni migliori (partire in un altro momento). Dobbiamo distinguere tra attività noiose e monotone, per le quali i software sono portati, ed attività che ad oggi sembrano perlopiù dei contrattempi ma che possiamo migliorare.

I “tempi morti” dal mio punto di vista sono importanti. Quante volte vi è capitato di avere un’idea mentre facevate tutt’altro? Magari proprio alla guida o mentre siete in bagno a farvi la barba? I “tempi morti” sono intervalli di tempo durante i quali non fate razionalmente una determinata attività, ma il vostro cervello – fidatevi – sta lavorando eccome. E dietro le quinte sta proprio lavorando a quel problema di AngularJS o WPF che vi affligge. Penso che per vivere e lavorare bene una persona debba assolutamente godere di tempi morti, passati davanti ad un videogioco, alla lettura di un libro, alla guida di un’auto durante una gita fuori porta, in coda alla cassa, in attesa alle Poste o all’ospedale. Come dicevo all’inizio, non siamo individui pensati per produrre e basta, ma dobbiamo soprattutto vivere. Ed i tempi morti sono parte della vita. Personalmente, per lavorare bene ed in modo efficace ho bisogno dei miei tempi di svago, e non riesco a switchare da un’attività all’altra a costo zero, come fa in modo continuo un PC. Prima di passare da un corso all’altro, per esempio, ho bisogno di tempo per fare altro, per staccare la spina un attimo, perchè non è per nulla semplice gestire classi di X persone parlando di tecnologia e di sviluppo del software.

Ritengo che il consumismo sfrenato ci stia un po’ facendo perdere parecchio di vista la bussola della nostra vita. Siccome abbiamo sempre più da fare, sempre più da leggere e da scrivere e da criticare, sempre più da correre e sempre più in fretta, siamo costantemente alla ricerca di blocchi di secondi e minuti da ritagliare qua e là. No, così non va. O perlomeno non è il modo in cui mi piace vivere.

Send to Kindle

Visual Studio 2017 ed il mese di aprile

Beh direi che di carne sul fuoco ce n’è abbastanza. Alla faccia di chi diceva che UWP è “poco considerato”. Ho raccolto qui sotto una serie di link tratti da MSDN sugli ultimi rilasci avvenuti nelle scorse ore per quanto riguarda Visual Studio 2017, .NET Framework, Universal Windows Platform.

Visual Studio 2017 Update
https://blogs.msdn.microsoft.com/visualstudio/2017/04/05/visual-studio-2017-update/

Visual Studio 2017 Performance Improvements
https://blogs.msdn.microsoft.com/visualstudio/2017/04/05/visual-studio-2017-performance-improvements/

Announcing the .NET Framework 4.7
https://blogs.msdn.microsoft.com/dotnet/2017/04/05/announcing-the-net-framework-4-7/

Updating your tooling for Windows 10 Creators Update
https://blogs.windows.com/buildingapps/2017/04/05/updating-tooling-windows-10-creators-update/#.WOXeGqlgXqU.twitter

Annoncing UWP Community Toolkit 1.4
https://blogs.windows.com/buildingapps/2017/04/03/announcing-uwp-community-toolkit-1-4/#.WOUMb6b_YB4.twitter#lyhX2JFgJp6liyL7.97

Windows 10 Creators Update SDK
https://blogs.msdn.microsoft.com/chuckw/2017/04/06/windows-10-creators-update-sdk/

Fresh Bits – Windows 10 Creators Update and Creators Update SDK
https://blogs.msdn.microsoft.com/marcelolr/2017/04/05/fresh-bits-windows-10-creators-update-and-creators-update-sdk/

Submissions using Windows 10, version 1703 are now being accepted!
https://blogs.msdn.microsoft.com/windows_hardware_certification/2017/04/05/submissions-using-windows-10-version-1703-are-now-being-accepted/

Team Explorer for TFS 2017
https://blogs.msdn.microsoft.com/bharry/2017/04/05/team-explorer-for-tfs-2017/

What’s new in Windows 10 Creators Update (Coming April 11)
https://blogs.msdn.microsoft.com/techtalks/windows-10/whats-new-in-windows-10-creators-update-coming-april-11/

Send to Kindle

Trello API su NuGet

Volevo segnalare la presenza di questi 3 package pubblicati su NuGet:

Manatee.Trello

Manatee.Trello.ManateeJson

Manatee.Trello.WebApi

Dopo la solita autenticazione effettuata via OAuth, avete tutta una serie di funzionalità read/write verso Trello, che vi permettono di leggere e scrivere bacheche, board, task e tutte le informazioni relative.

Ho provato, giusto per curiosità, le funzionalità di base, e ci sono tutte. Magari può interessare a qualcuno di voi in ascolto, magari per realizzare un client di qualche tipo, preferibilmente desktop (WPF) o meglio ancora UWP!

Smile

Send to Kindle

Documentazione UWP in formato PDF

E se vi dicessi che ci sono 5133 pagine di documentazione su UWP che vi stanno aspettando?

Mi è capitato sottomano un tweet, oggi, parecchio interessante.

You can download all Windows UWP docs in PDF form.

Ero già al corrente del fatto che la documentazione ufficiale UWP fosse stata spostata sul nuovo portale, ma onestamente questa news del formato PDF mi era proprio sfuggita. Detto questo, è sufficiente per esempio raggiungere l’url https://docs.microsoft.com/en-us/windows/uwp/get-started/your-first-app ed effettivamente in basso a destra c’è un bel link:

image

Cliccando il link, parte il download del file PDF. Se lo si fa con Edge, il download sembra che abbia qualcosa che non vada: appare il tradizionale viewer dei PDF, sembra che non stia scaricando nulla. L’ho fatto con Chrome e la cosa va un po’ meglio: c’è una progress-bar che mostra chiaramente il download in corso.

L’unico problema?
Il file pesa 54,5Mb, e comprende ben 5133 pagine di documentazione.
Buona lettura!

Send to Kindle

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

[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

[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

[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