Technology Experience
.NET WorldVisualStudioTips.net

[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

Igor Damiani

La sua passione per l'informatica nasce nella prima metà degli anni '80, quando suo padre acquistò un Texas Instruments TI-99. Da allora ha continuato a seguire l'evoluzione sia hardware che software avvenuta nel corso degli anni. E' un utente, un videogiocatore ed uno sviluppatore software a tempo pieno. Igor ha lavorato e lavora anche oggi con le più moderne tecnologie Microsoft per lo sviluppo di applicazioni: .NET Framework, XAML, Universal Windows Platform, su diverse piattaforme, tra cui spiccano Windows 10 piattaforme mobile. Numerose sono le app che Igor ha creato e pubblicato sul marketplace sotto il nome VivendoByte, suo personale marchio di fabbrica. Adora mantenere i contatti attraverso Twitter e soprattutto attraverso gli eventi delle community .NET.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.