WPF: dal DataBinding ai Template - Terza parte

5 pagine in totale: <<Indietro 1 2 [3] 4 5 Avanti >>

Personalizzare un controllo con ControlTemplate

Fortunatamente i DataTemplate non sono l'unico tipo di template disponibili e abbiamo già conosciuto gli ItemsPanelTemplate nell'articolo "I controlli di elenco presenti in WPF", ma rimane un'unica ancora inesplorata classe derivata da FrameworkTemplate: il ControlTemplate.

Ogni controllo di WPF espone una proprietà Template di tipo ControlTemplate definito nella classe Control. Mediante esso è possibile ridefinire completamente l'intero visual tree di un controllo, alterando in modo anche radicale il suo aspetto. Questa è una delle più importanti caratteristiche degli elementi dell'interfaccia di WPF che gli è valsa l'appellativo di Look Less, in altre parole privi di look. In realtà ogni controllo di WPF ha già definito per default un proprio aspetto, ma questo è sempre ottenuto mediante l'utilizzo di un oggetto ControlTemplate.

Se in un primo momento ControlTemplate e Style sembrano sovrapporsi, basta ricordare che mentre con gli stili possiamo definire l'aspetto impostando solamente le proprietà che lo sviluppatore del controllo ha definito, con ControlTemplate è possibile stravolgere completamente l'aspetto di un controllo. E' anche per questo motivo che i controlli in WPF non espongono proprietà specifiche per definirne l'aspetto e questo principalmente perché un bottone potrebbe non assomigliare per niente alla nostra idea di pulsante.

Come sappiamo mediante l'uso degli stili possiamo impostare ogni proprietà del controllo e non fa eccezione la proprietà Template la quale definisce l'aspetto del controllo. Per raggiungere l'agognata separazione tra aspetto e logica modifichiamo i DataTemplate utilizzati fino adesso, rimuovendo bordo e sfondo che sposteremo nel ControlTemplate del controllo ListBoxItem.

L'oggetto ListBoxItem è il contenitore dei nostri DataTemplate e ne impostiamo la proprietà Template con uno stile.

<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}"> 
  <Setter Property="Padding" Value="5"></Setter> 
  <Setter Property="Template"> 
    <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ListBoxItem}"> 
        <Border Name="Border" Padding="15" CornerRadius="10"> 
          <Border.Background> 
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> 
              <GradientStop Color="DarkGray" Offset="0.0" /> 
              <GradientStop Color="Black" Offset="1.0" /> 
            </LinearGradientBrush> 
          </Border.Background> 
          <ContentPresenter /> 
        </Border> 
        <ControlTemplate.Triggers> 
          <DataTrigger Binding="{Binding Path=EditorPrize}"> 
            <DataTrigger.Value> 
              <FairPlay:EditorPrize>BestGamePlay</FairPlay:EditorPrize> 
            </DataTrigger.Value> 
            <Setter TargetName="Border" Property="BorderThickness" Value="5"/> 
            <Setter TargetName="Border" Property="BorderBrush" Value="Gold"/> 
          </DataTrigger> 
          <DataTrigger Binding="{Binding Path=Game.Genre}"> 
            <DataTrigger.Value> 
              <FairPlay:GameGenre>Rpg</FairPlay:GameGenre> 
            </DataTrigger.Value> 
            <Setter TargetName="Border" Property="Background"> 
              <Setter.Value> 
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> 
                  <GradientStop Color="LightSlateGray" Offset="0.0" /> 
                  <GradientStop Color="SteelBlue" Offset="1.0" /> 
                </LinearGradientBrush> 
              </Setter.Value> 
            </Setter> 
          </DataTrigger> 
          <Trigger Property="IsSelected" Value="true"> 
            <Setter TargetName="Border" Property="Background"> 
              <Setter.Value> 
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> 
                  <GradientStop Color="White" Offset="0.0" /> 
                  <GradientStop Color="Gold" Offset="1.0" /> 
                </LinearGradientBrush> 
              </Setter.Value> 
            </Setter> 
          </Trigger> 
        </ControlTemplate.Triggers> 
      </ControlTemplate> 
    </Setter.Value> 
  </Setter> 
</Style> 

ControlTemplate su ListBoxItem

L'aspetto è quello noto già raggiunto mediante l'utilizzo delle DataTemplate, ma stavolta possiamo individuare senza esitazione l'item selezionato e tutto senza intervenire sul layout del DataTemplate che continuano a fornire mediante l'inserimento dell'oggetto ContentPresenter. Dal potere di ridefinire completamente l'aspetto del controllo deriva naturalmente una grande responsabilità: è sufficiente dimenticare o rimuovere l'oggetto ContentPresenter per compromettere la visualizzazione e l'aspetto nella nostra ListBox. Per sapere quando il nostro template deve avere nel suo visual tree un oggetto di tipo ContentPresenter è sufficiente controllare che la classe base sia del tipo ContentControl.

5 pagine in totale: <<Indietro 1 2 [3] 4 5 Avanti >>

Contenuti dell'articolo

Commenti
Dai un voto a questo articolo, ci aiuterà a migliorare il nostro sito (1 è il voto minimo, 5 il massimo).

Per procedere al rating dell'articolo devi essere autenticato.

Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.

TUTORIALS


IN EVIDENZA
MISC