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>

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.
Contenuti dell'articolo
- Le novità del .NET Framework 3.5 SP1 in Windows Presentation Foundation
- Introduzione a .NET Micro Framework
- Gestire transazioni miste con NTFS in Windows Server 2008
- Windows Presentation Foundation 3.5: 3D interattivo e le altre novità del framework
- Le novità di Communication e Workflow Foundation e la loro cooperazione nel .NET Framework 3.5
- .NET Framework 3.5 e Visual Studio 2008: cosa c'è di nuovo
- Gestione delle eccezioni in Windows Communication Foundation
- Sviluppare workflow sequenziali con WF
- WPF: dal DataBinding ai Template - Seconda parte
Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.






Difficoltà
Stampa
Download 


10annidi.ASPItalia.com: iscriviti alla competizione e vinci fantastici premi ogni mese!