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
Ricevere notifiche sui test con Azure Load Testing
Creare un webhook in Azure DevOps
Creare una libreria CSS universale: Nav menu
Migliorare la sicurezza dei prompt con Azure AI Studio
Introduzione ai web component HTML
Fissare una versione dell'agent nelle pipeline di Azure DevOps
Ordinare randomicamente una lista in C#
Gestione degli eventi nei Web component HTML
Utilizzare la funzione EF.Parameter per forzare la parametrizzazione di una costante con Entity Framework
Utilizzare Container Queries nominali
Ottenere un token di accesso per una GitHub App
Utilizzare il metodo ExceptBy per eseguire operazione di sottrazione tra liste
I più letti di oggi
- Formati per l'impostazione del colore in CSS3
- Eseguire una chiamata AJAX per inviare dati al server in Angular 2
- Impostare un riferimento ad una entity collegata tramite foreign key
- la Call For Papert per #netconfit è aperta!invia la tua sessione da https://aspit.co/netconfit-20 puoi parlare di #net5, #aspnet5, #efcore5, #CSharp9 e tutto quello che ruota intorno a #dotnet.