Luca Regnicoli

Avalon databinding

Nella CTP di marzo di Avalon e Indigo era possibile personalizzare il meccanismo di composition del visual tree in xaml solo tramite stili.
Stop! Fermiamoci un attimo, magari non tutti sanno che roba è..  Una caratteristica fondamentale di Avalon è la possibilità di creare oggetti complessi da oggetti semplici, senza utilizzare subclassing. Il meccanismo in questione si chiama composition e ha come "capo" il composition engine. Questo permette di creare, ad esempio un pulsante con dentro un'immagine semplicemente:

<Button Content="Cliccami">
     <Image Source="signorina.jpg"/>
<Button>

La "composizione" finale viene chiamata Visual Tree e ogni singolo elemento (il buttone e l'immagine) è chiamato Visual.
Se volessimo componentizzare questo nostro Visual Tree, per evitare quindi in ogni Window/Page di riderifinire l'oggetto (sai che scatole...), nella versione precedente di Avalon si poteva intervenire solo tramite gli stili, ovvero:

<Style x:Key="PulsanteConSignorina">
  <Button />
   <Style.VisualTree>
    <Canvas>  
     <Button  Content="*Alias(Target=Content)">
         <Image Source="signorina.jpg"/>  
    </Button> 
    </Canvas>
   </Style.VisualTree>
</Style>

e usarlo semplicemente con <Button Content="Cliccami" Style="{StaticResource PulsanteConSignorina}" />. Notate la sintassi di binding che imposta il Content del Visual al valore della proprietà Content dell'oggetto "stilizzato", tale sintassi è *Alias(Target=Content) e mi sembra semplice e immediata da ricordare, no??? :-).

Nella Beta1 RC abbiamo due differenti strade per personalizzare il comportamento di un Visual Tree e per componentizzarlo in oggetti riciclabili sull'applicazione o sulla pagina:
ControlTemplate, l'idea è simile a quella precedente, ovvero personalizziamo la composizione tramite stili:

    <Style TargetType="{x:Type Button}" x:Key="PulsanteConSignorina" >
      <Style.Setters>
        <Setter Property="Margin" Value="1,2,1,2"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
              <Canvas> 
                <Button Content="{TemplateBinding Content}"><Image Source=".." /><Button>
               </Canvas>
             </ControlTemplate>
           </Setter.Value>
         </Setter>
       </Style.Setters>
     </Style>

Da notare il TargetType nella dichiarazione dello stile, la mancanza della definizione di <Button/> come prima riga dello stile (ottima cosa :-)), e l'arrivo del nuovo elemento Setter che non è una razza di cane :-) ma un modo per impostare con chiavi/valori o chiavi e compound property, delle proprietà del Visual. Caruccia anche la nuova sintassi di binding: {TemplateBinding Content}.
Questo stile può essere utilizzato come Resource (per XAML una Resource è un modo per riutilizzare oggetti di markup) all'interno di una pagina o dell'intera applicazione. Nel caso dell'applicazione è sufficiente inserire nel file xaml che conterrà la definizione dell'applicazione:

<Application
    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">
  <Application.Resources>
    <Style TargetType="{x:Type Button}" x:Key="PulsanteConSignorina" > ....
 </Application.Resources>
</Application>
 

Un altro sistema per personalizzare il Visual Tree è tramite un DataTemplate: di diverso rispetto al ControlTemplate è la funzione, il DataTemplate serve per personalizzare l'aspetto di una singolo elemento di dati, ad esempio un ListBoxItem, evitando di cablare nel codice di ogni listbox l'aspetto dei propri item. Come concetto a me ricorda molto l'ItemTemplate del Repeater di ASP.NET.

 <DataTemplate x:Key="TemplateValutazioni">
      <Canvas Width="300" Height="20">
        <TextBlock Width="180" TextContent="{Binding Path=Auto}"/>
        <TextBlock  Width="80"  TextContent="{Binding Path=Prezzo}"/>
      </Canvas>
 </DataTemplate>
 
e l'utilizzo è il seguente: <ListBox Name="auto" ItemTemplate="{StaticResource TemplateValutazioni}"/>