Prima del .NET 3.0 le Web apps erano scritte con markup langs, mentre le Win Apps non potevano esserlo. Il FW 3.0 ha cambiato questa situazione introducendo lo XAML (pron. zzzzzamel), eXtensible Application Markup Language, che ha 2 caratteristiche fondamentali:

1) E’ un linguaggio di markup (come l’html) per creare Win Apps
2) Quasi tutti gli oggetti XAML hanno un oggetto corrispondende nel CLR; la maggior parte di cio’ che si crea con XAML puo’ essere creato con programmi C#/VB.NET

Per fare un esempio:

<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Label Content="Hello Cris" FontFamily="Tahoma" FontSize="24"></Label>
</Grid>
</Window>

Il tag <Label/> equivale a System.Windows.Control con tutte le sue proprieta’ e i suoi metodi.

I files xaml, in qualita’ di xml, devono essere ben formati, quindi occorre seguire le regole di Case, di Quotes e quant’altro.

Control Elements

I controls possono essere classificati in:

  • Simple controls - non hanno le proprieta’ Content, Header e Item. Es. Image, Frame
  • Content controls - hanno la proprieta Content e possono quindi contenere anche oggetti al loro interno (es Button, TextBox)
  • Item controls - contengono al loro interno una collezione di controls
  • Header item controls - non hanno l’attributo Content ma hanno l’attributo Header (es. MenuItem)
  • Headered content controls - possono avere il Content e l’header, ma non Item (cioe’ solo un livello di contenuto, ad es. l’Expander)

Document elements

Una caratteristica innovativa di XAML e’ la possibilita di visualizzare i documenti, oltre che col classico FixedDocument, con il FlowdDocument, come nell’esempio che segue:

<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<FlowDocument>
<Paragraph>Paragrafo 1</Paragraph>
<Paragraph>Paragrafo 2</Paragraph>
<Paragraph>Paragrafo 3</Paragraph>
<Paragraph>Paragrafo 4</Paragraph>
<Paragraph>Paragrafo 5</Paragraph>
<Paragraph>Paragrafo 6</Paragraph>
<Paragraph>Paragrafo 7</Paragraph>
<Paragraph>Paragrafo 8</Paragraph>
<Paragraph>Paragrafo 9</Paragraph>
<Paragraph>Paragrafo 10</Paragraph>
</FlowDocument>
</Window>

L’output e’ comodissimo e apre la porta a molte possibilita’ di impaginazione:

ma anche:

Questa magia accade grazie al fatto che XAML, in qualita’ di parte di WPF, riesce ad aggiustare e raggruppare le pagine in base alla risoluzione dello schermo.

Quando si deve disegnare una semplice interfaccia, si possono utilizzare diverse sottoclassi di Panel: DockPanel, StackPanel o Grid (forse per cose piu’ complesse); lo scopo di questi elementi e’ favorire e gestire la posizione degli altri oggetti sullo schermo.

Il DockPanel permette di attaccare quelli che in html sono dei div in modo da realizzare facilmente una classica struttura header, menu left e main:

<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">

<DockPanel>
<Border Height=”70″ Width=”300″ DockPanel.Dock=”top” HorizontalAlignment=”Center”
BorderBrush=”YellowGreen” BorderThickness=”1″>
<Label Content=”Top banner” FontSize=”32″></Label>
</Border>
<Border Height=”220″ Width=”100″ DockPanel.Dock=”Left” BorderBrush=”RosyBrown” BorderThickness=”1″>
<Label Content=”Left side” FontSize=”14″></Label>
</Border>
<Border Height=”220″ Width=”200″ DockPanel.Dock=”Left” BorderBrush=”LavenderBlush” BorderThickness=”1″>
<Label Content=”Right side” FontSize=”14″></Label>
</Border>
</DockPanel>
</Window>
Che produce:

La Grid

Il Panel piu’ flessibile e’ senz’altro la Grid, che analogamente alla table html da’ pieno controllo su righe e colonne:


<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock FontSize="36" Foreground="white" Background="Blue" Grid.Column="0" Grid.Row="0" Text="1"></TextBlock>
<TextBlock FontSize="36" Background="Gold" Grid.Column="1" Grid.Row="0" Text="2"></TextBlock>
<TextBlock FontSize="36" Foreground="white" Background="Crimson" Grid.Column="2" Grid.Row="0" Text="3"></TextBlock>
<TextBlock FontSize="36" Background="White" Grid.Column="0" Grid.Row="1" Text="4"></TextBlock>
<TextBlock FontSize="36" Foreground="White" Background="Purple" Grid.Column="1" Grid.Row="1" Text="5"></TextBlock>
<TextBlock FontSize="36" Foreground="white" Background="Green" Grid.Column="2" Grid.Row="1" Text="6"></TextBlock>
<TextBlock FontSize="36" Background="AliceBlue" Grid.Column="0" Grid.Row="2" Text="7"></TextBlock>
<TextBlock FontSize="36" Foreground="Black" Background="Bisque" Grid.Column="1" Grid.Row="2" Text="8"></TextBlock>
<TextBlock FontSize="36" Foreground="white" Background="DarkOrange" Grid.Column="2" Grid.Row="2" Text="9"></TextBlock>
</Grid>
</Window>

Produce:

Effetti carini
Gradiente:

<Window.Resources>
<LinearGradientBrush x:Key="ButtonGradient">
<GradientStop Color="Red" Offset="0"></GradientStop>
<GradientStop Color="LimeGreen" Offset="0.8"></GradientStop>
</LinearGradientBrush>
</Window.Resources>
<Button Background="{DynamicResource ButtonGradient}" Width="150" Height="40"></Button>

Rotazione di oggetti:

<StackPanel>
<Button Content="Press me" Background="LimeGreen" Foreground="White" Width="100">
</Button>
<Button Content="i'm rotated" Background="Beige" Foreground="White" Width="100">
<Button.RenderTransform>
<RotateTransform Angle="30"></RotateTransform>
</Button.RenderTransform>
</Button>
<Button Content="me too" Background="DarkRed" Foreground="White" Width="100">
<Button.RenderTransform>
<RotateTransform Angle="60"></RotateTransform>
</Button.RenderTransform>
</Button>

</StackPanel>