La ListBox è senza ombra di dubbio uno dei controlli più utilizzati di Silverlight, sia per le funzionalità, come la sincronizzazione con le collezioni che implementano ICollectionView, sia per la facilità con la quale è possibile impostarne l'aspetto.
Utilizzando le caratteristiche del Visual State Manager è possibile personalizzare, anche in maniera estrema, l'aspetto della ListBox. Ci sono però alcuni particolari, come il colore di Foreground, che è difficile personalizzare se non limitando la possibilità di riutilizzare la template.
È utile ricordare l'anatomia che determina l'aspetto si una ListBox: la proprietà ItemTemplate determina la template da utilizzare per visualizzare i dati, mentre ItemContainerStyle determina l'aspetto del contenitore.
Un modo per modificare la selezione ed il colore di Foreground di un ListBoxItem è modificarne la template, e sostituire il ContentPresenter con una TextBlock. Questa modifica è più che lecita, ma di fatto impedisce di utilizzare qualsiasi tipo di DataTemplate ed è poco riutilizzabile.
Per aggirare questo problema possiamo realizzare un semplice Behavior, creiamo quindi una nuova classe che estenda il tipo Behavior:
public class SetSelectedItemForegroundBehavior : Behavior<ListBox>{}Abbiano assegnato al Typed Argument il tipo ListBox, questo limita l'utilizzo di questo behavior al tipo ListBox e tipizza fortemente la proprietà AssociatedObject che il tipo Behavior<T> espone.
Proseguiamo dichiarando un campo di tipo Brush, nel quale salveremo il colore corrente dell'elemento non ancora selezionato e una DependendyProperty per impostare il colore che deve assumere dopo la selezione.
private Brush originalBush;
public Color SelectedColorProperty
{
get { return ( Color)GetValue(SelectedColorPropertyProperty); }
set { SetValue(SelectedColorPropertyProperty, value); }
}Eseguiamo l'override del metodo OnAttached e registriamoci per l'evento SelectionChanged:
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}Il metodo è abbastanza semplice e si limita a recuperare l'elemento selezionato e ad impostarne il colore oltre a reimpostare il colore originale dell'elemento deselezionato:
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}
void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
if (e.AddedItems[0] is ListBoxItem)
{
ListBoxItem item = (ListBoxItem)e.AddedItems[0];
originalBush = item.Foreground;
item.Foreground = new SolidColorBrush(SelectedColorProperty);
}
else
{
Action a = null;
a = () =>
{
ListBoxItem listBoxItem = AssociatedObject.ItemContainerGenerator.ContainerFromItem(e.AddedItems[0]) as ListBoxItem;
if (listBoxItem != null)
listBoxItem.Foreground = new SolidColorBrush(Colors.White);
else
Dispatcher.BeginInvoke(a);
};
Dispatcher.BeginInvoke(a);
}
}
if (e.RemovedItems.Count > 0)
{
if (e.RemovedItems[0] is ListBoxItem)
{
((ListBoxItem)e.RemovedItems[0]).Foreground = originalBush;
}
else
{
Action a = null;
a = () =>
{
ListBoxItem listBoxItem = AssociatedObject.ItemContainerGenerator.ContainerFromItem(e.RemovedItems[0]) as ListBoxItem;
if (listBoxItem != null)
listBoxItem.Foreground = new SolidColorBrush(Colors.Black);
else
Dispatcher.BeginInvoke(a);
};
Dispatcher.BeginInvoke(a);
}
}
}L'unica cosa particolare da notare è l'utilizzo di un ciclo per recuperare il ListBoxItem in caso la lista sia creata da DataBind piuttosto che da XAML. Questo espediente è necessario in quanto non è possibile determinare a priori quando il ListBoxItem verrà creato, poiché tutto il processo è asincrono.
Non ci resta che compilare il nostro Behavior e associarlo alla nostra ListBox, ed in seguito impostare il colore da associare all'elemento selezionato.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Monitorare le tabelle di Azure SQL Database con Change Event Streaming
Gestione dei prompt file a livello di organizzazione aziendale in GitHub
Abilitare .NET 10 su Azure App Service e Azure Functions
Ottimizzare i costi con Smart tier in Azure Blob Storage
Utilizzare i named query filter di Entity Framework
Effettuare chiamate API tramite GitHub App
Integrare Agenti A2A in Azure API Management
Migliorare accessibilità e interazioni nelle pagine HTML con gli attributi inert e autofocus
Usare la parola chiave field per semplificare la scrittura di proprietà in C#
Supporto nativo a JSON in SQL Server 2025
Utilizzo delle Feature flag in ASP.NET Core
Come automatizzare il download dei report di billing da GitHub Enterprise


