WinRT ci mette a disposizione un nuovo controllo SemanticZoom che permette allo sviluppatore di definire due viste della stessa collection utile per facilitare l'utente nella ricerca di elementi "raggruppati"; il tutto è illustrato chiaramente in un esempio nell'SDK.
Nell'esempio dell'SDK, il controllo (nel caso specifico una GridView) che ospiterà la vista ZoomedInView che rappresente la visualizzazione "standard" del controllo è correttamente settata nello XAML sfruttando il DataBinding; invece la CollectionViewSource della vista ZoomedOutView ovvero la vista pensata proprio per facilitare l'utente nella sua ricerca; viene inizializzata nel CodeBehind della pagina nel costruttore, e cercando in rete si trovano praticamente solo esempi identici a quello dell'SDK; al limite l'inizializzazione dello ZoomedOutView è fatta nel metodo OnNavigatedTo sempre della View.
Questo approccio funziona senza problemi se i nostri dati (ed i relativi gruppi) sono conosciuti a priori; ma mostra tutti i suoi limiti nel caso sia necessario che i dati e relativo raggruppamento avvengano in un servizio esterno. In questo caso, il controllo ZoomedOutView non mostra nulla in quanto nel costruttore della pagina la collection risulta ancora vuota (visto che le chiamate a servizi esterni devono essere asincrone) e quindi il controllo diventa completamente inutilizzabile per l'utente.
Cercando una soluzione intelligente al problema penso che la soluzione migliore sia utilizzare un semplice converter:
public class CollectionViewSourceToCollectionGroupsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
object result = null;
try
{
var cvs = value as ICollectionView;
if (cvs != null)
{
result = cvs.CollectionGroups;
}
}
catch (Exception ex)
{
result = null;
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Così possiamo semplicemente specificare lo stesso CollectionViewSource per entrambe le viste (ZoomedInView e ZoomedOutView) e sfruttare appieno il motore di DataBinding.