Nell'articolo sul controllo PivotViewer
(https://www.silverlightitalia.com/articoli/silverlight/pivotviewer-v2-silverlight-5.0.aspx), disponibile nell'SDK di Silverlight 5.0, abbiamo introdotto le possibilità di personalizzazione del layout delle trading cards attraverso gli adorner.
Oltre a PivotViewerDefaultItemAdorner, abbiamo la possibilità di realizzare adorner completamente custom, per inserire la nostra grafica personalizzata ed altri elementi interattivi.
Per questa operazione possiamo creare un nostro UserControl che andremo ad inserire come controllo principale del ControlTemplate dello Style di PivotViewerItemAdorner.
Lo UserControl (nell'esempio MyAdorner.xaml) può essere realizzato come vogliamo, l'unico accorgimento da seguire è quello di utilizzare il controllo Viewbox come contenitore degli elementi.
Il controllo Viewbox permette l'adattamento della grandezza del contenuto in funzione della sua grandezza, ed è quindi perfetto per la visualizzazione all'interno di una trading card, il cui template viene utilizzato per più livelli di zoom.
Per mantenere una proporzione corretta del layout dell'adorner è corretto assegnare al primo controllo contenuto dentro il Viewbox, le stesse dimensioni assegnate alle varie template delle trading card.
L'adorner, infatti, viene visualizzato intorno ad ogni card per tutti i livelli di zoom, quindi siamo abbastanza certi di questa corrispondenza di proporzioni.
<Style x:Key="MyAdorner"
TargetType="sdk:PivotViewerItemAdorner">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="ButtonBorder">
<EasingDoubleKeyFrame KeyTime="0"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>
<VisualStateGroup x:Name="ItemStates">
<VisualState x:Name="Default" />
<VisualState x:Name="IsSelected" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<local:MyAdorner DataContext="{Binding}"
Visibility="{Binding IsItemSelected, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BoolToVisibilityConverter}}" />
<Border x:Name="ButtonBorder"
Margin="-1"
BorderThickness="4"
BorderBrush="Red"
Opacity="1" />
<Border Visibility="{Binding IsItemSelected, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BoolToVisibilityConverter}}"
Margin="-1"
BorderThickness="4"
BorderBrush="Black"
Opacity="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>Come possiamo vedere nel codice, l'altro accorgimento da seguire è quello di bindare la visibilità dello UserControl MyAdorner alla proprietà IsItemSelected della trading card. In questo modo il nostro adorner custom apparirà solo quando la card è esplicitamente selezionata e attiva.
Nel template dell'adorner possiamo personalizzare anche il bordo e altri elementi che identifichino la card attiva o in mouse over; inoltre abbiamo sempre a disposizione l'entità DataContext da poter trasferire ed utilizzare nello UserControl.
Con pochissimo markup possiamo ottenere il seguente risultato.

Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Gestire progetti .NET + React in .NET Aspire
Semplificare i deployment con le label in Azure Container App
Mischiare codice server side e client side in una query LINQ con Entity Framework
Interagire con Azure DevOps tramite MCP Server
DevSecOps per .NET: dalla teoria alla pratica
Selettore CSS :has() e i suoi casi d'uso avanzati
Utilizzare Hybrid Cache in .NET 9
Utilizzare WhenEach per processare i risultati di una lista di task
Utilizzare il metodo ExceptBy per eseguire operazione di sottrazione tra liste
Anonimizzare i dati sensibili nei log di Azure Front Door
Collegare applicazioni server e client con .NET Aspire
Scrivere selettori CSS più semplici ed efficienti con :is()


