Ma che cosa è successo nel frattempo alla nostra query string? In estrema sintesi, al momento dell'attivazione della pagina di ricerca viene invocato (passando dal metodo OnNavigatedTo che intercetta l'evento di attivazione della pagina) il metodo LoadState, il quale riceve come parametro proprio la stringa di ricerca introdotta dall'utente.
Ecco il listato completo del metodo LoadState, proposto di default dal contratto di search nella pagina SearchResultPage1, cui spetta di ricevere la richiesta dell'utente e di elaborare i relativi risultati:
protected override void LoadState(Object navigationParameter, Dictionary pageState)
{
var queryText = navigationParameter as String;
// (omissis)
var filterList = new List();
filterList.Add(new Filter("All", 0, true));
// Communicate results through the view model
this.DefaultViewModel["QueryText"] = '\u201c' + queryText + '\u201d';
this.DefaultViewModel["Filters"] = filterList;
this.DefaultViewModel["ShowFilters"] = filterList.Count > 1;
}
Questa classe utilizza il DefaultViewModel per mettere in binding i risultati della ricerca e per esporre alcune informazioni relative alla ricerca stessa, come la query string utilizzata, l'elenco dei filtri disponibili (in questo caso, un generico filtro "All") e il numero di record trovati.
Ciò che dobbiamo fare è aggiungere, nel Biz
, un metodo che permetta (seppur in modo primitivo) di operare la ricerca sui campi che ci interessano e ci restituisca l'elenco delle voci che soddisfano il criterio di ricerca; questo metodo verrà poi richiamato nel metodo LoadData
sopra illustrato, passando come parametro la query string digitata dall'utente.
Ecco il metodo da aggiungere alla classe Biz:
public List SearchBikes(String bikeName)
{
return this.GetAllBikes().Where(m => m.BikeName.Contains(bikeName)).ToList();
}
Ora modifichiamo il metodo LoadData del contratto di ricerca in modo da ottenere l'elenco di entità che soddisfano i criteri di ricerca inseriti dall'utente, elenco che dovrà essere messo in binding con il DefaultViewModel utilizzato dalla pagina per mostrare i risultati.
Già che ci siamo, modifichiamo il filtro di default, affinché mostri il numero di record trovati (bikes.Count), e visualizziamolo a schermo (filterList.Count >= 1). In grassetto sono evidenziate le modifiche apportate al codice:
protected override void LoadState(Object navigationParameter, Dictionary pageState)
{
var queryText = navigationParameter as String;
// Ricerco le bici
var biz = new Biz();
var bikes = biz.SearchBikes(queryText);
// TODO: Application-specific searching logic. The search process is responsible for
// creating a list of user-selectable result categories:
//
// filterList.Add(new Filter("", ));
//
// Only the first filter, typically "All", should pass true as a third argument in
// order to start in an active state. Results for the active filter are provided
// in Filter_SelectionChanged below.
var filterList = new List();
filterList.Add(new Filter("All", bikes.Count, true));
// Communicate results through the view model
this.DefaultViewModel["Results"] = bikes;
this.DefaultViewModel["QueryText"] = '\u201c' + queryText + '\u201d';
this.DefaultViewModel["Filters"] = filterList;
this.DefaultViewModel["ShowFilters"] = filterList.Count >= 1;
}
L'ultima modifica consiste mostrate a video le proprietà delle entità che ci interessano. Per far questo è sufficiente modificare il controllo GridView denominato resultsGridView
nel modo che segue:
<GridView
x:Name="resultsGridView"
AutomationProperties.AutomationId="ResultsGridView"
AutomationProperties.Name="Search Results"
TabIndex="1"
Grid.Row="1"
Margin="0,-238,0,0"
Padding="110,240,110,46"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemsSource="{Binding Source={StaticResource resultsViewSource}}">
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding BikeName}" Margin="0,20,0,0" Foreground="#7CFFFFFF" HorizontalAlignment="Left" />
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="Control">
<Setter Property="Height" Value="70"/>
<Setter Property="Margin" Value="0,0,38,8"/>
</Style>
</GridView.ItemContainerStyle>
</GridView>
Effettuiamo un nuovo deployment dell'applicazione e proviamo ad attivare il charm di ricerca inserendo un qualsiasi testo da ricercare. Ecco il risultato:
Sebbene in questo esempio ci siamo limitati a restituire delle semplici stringhe di testo, non c'è alcun limite al tipo di dati e contenuti da mostrare come risultato della ricerca (immagini, contenuti multimediali, impostazioni di configurazione, ecc.). Non solo, ma è anche possibile sfruttare le API esposte da WinRT per offrire all'utente dei suggerimenti mentre sta digitando il testo da ricercare.
Come abbiamo visto, implementare il contratto di ricerca è molto semplice; se non consideriamo la parte grafica e la logica interna di ricerca che ovviamente potrebbe essere molto complessa, è sufficiente aggiungere il Search Contract al progetto, scegliere un nome per la pagina di ricerca e modificarla per visualizzare i risultati nel modo più adatto.