Xamarin.Forms Ricerca shell

Xamarin.Forms Shell include funzionalità di ricerca integrate fornite dalla SearchHandler classe . La funzionalità di ricerca può essere aggiunta a una pagina impostando la Shell.SearchHandler proprietà associata su un oggetto sottoclassato SearchHandler . Come conseguenza, viene aggiunta una casella di ricerca nella parte superiore della pagina:

Screenshot di un gestore di ricerca shell in iOS e Android

Quando viene immessa una query nella casella di ricerca, la proprietà Query viene aggiornata e a ogni aggiornamento viene eseguito il metodo OnQueryChanged. È possibile eseguire l'override di questo metodo per popolare l'area dei suggerimenti di ricerca con dati:

Screenshot dei risultati di una ricerca in un gestore di ricerca shell, in iOS e Android

Quando viene selezionato un risultato nell'area dei suggerimenti di ricerca, viene quindi eseguito il metodo OnItemSelected. È possibile eseguire l'override di questo metodo per rispondere in modo appropriato, ad esempio passando a una pagina di dettagli.

Creare un oggetto SearchHandler

La funzionalità di ricerca può essere aggiunta a un'applicazione shell creando sottoclassi della classe SearchHandler ed eseguendo l'override dei metodi OnQueryChanged e OnItemSelected:

public class AnimalSearchHandler : SearchHandler
{
    public IList<Animal> Animals { get; set; }
    public Type SelectedItemNavigationTarget { get; set; }

    protected override void OnQueryChanged(string oldValue, string newValue)
    {
        base.OnQueryChanged(oldValue, newValue);

        if (string.IsNullOrWhiteSpace(newValue))
        {
            ItemsSource = null;
        }
        else
        {
            ItemsSource = Animals
                .Where(animal => animal.Name.ToLower().Contains(newValue.ToLower()))
                .ToList<Animal>();
        }
    }

    protected override async void OnItemSelected(object item)
    {
        base.OnItemSelected(item);

        // Let the animation complete
        await Task.Delay(1000);

        ShellNavigationState state = (App.Current.MainPage as Shell).CurrentState;
        // The following route works because route names are unique in this application.
        await Shell.Current.GoToAsync($"{GetNavigationTarget()}?name={((Animal)item).Name}");
    }

    string GetNavigationTarget()
    {
        return (Shell.Current as AppShell).Routes.FirstOrDefault(route => route.Value.Equals(SelectedItemNavigationTarget)).Key;
    }
}

L'override di OnQueryChanged ha due argomenti: oldValue, che contiene la query di ricerca precedente, e newValue, che contiene la query di ricerca corrente. L'area dei suggerimenti per la ricerca può essere aggiornata impostando la proprietà SearchHandler.ItemsSource su una raccolta IEnumerable contenente elementi che corrispondono alla query di ricerca corrente.

Quando un risultato della ricerca viene selezionato dall'utente, viene eseguito l'override di OnItemSelected e la proprietà SelectedItem viene impostata. In questo esempio, il metodo consente di passare a un'altra pagina che visualizza i dati sull'oggetto Animal selezionato. Per altre informazioni sulla navigazione, vedere Xamarin.Forms Spostamento nella shell.

Nota

È possibile impostare proprietà aggiuntive di SearchHandler per controllare l'aspetto della casella di ricerca.

Utilizzare un oggetto SearchHandler

La sottoclassata può essere utilizzata impostando la Shell.SearchHandler proprietà associata su un oggetto del tipo sottoclassatoSearchHandler, nella pagina di utilizzo:

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler Placeholder="Enter search term"
                                      ShowsResults="true"
                                      DisplayMemberName="Name" />
    </Shell.SearchHandler>
    ...
</ContentPage>

Il codice C# equivalente è il seguente:

Shell.SetSearchHandler(this, new AnimalSearchHandler
{
    Placeholder = "Enter search term",
    ShowsResults = true,
    DisplayMemberName = "Name"
});

Il metodo AnimalSearchHandler.OnQueryChanged restituisce un oggetto List contenente oggetti Animal. La proprietà DisplayMemberName è impostata sulla proprietà Name di ogni oggetto Animal, quindi i dati visualizzati nell'area dei suggerimenti corrispondono al nome di ogni animale.

La proprietà ShowsResults è impostata su true, quindi quando l'utente immette una query di ricerca vengono visualizzati i suggerimenti per la ricerca:

Screenshot dei risultati della ricerca in shell SearchHandler, in iOS e Android, con risultati per la stringa parziale M.

Quando la query di ricerca cambia, l'area dei suggerimenti per la ricerca viene aggiornata:

Screenshot dei risultati della ricerca in un gestore di ricerca shell, in iOS e Android, con risultati per la stringa parziale M o n.

Quando viene selezionato un risultato della ricerca, MonkeyDetailPage viene spostato su e viene visualizzata una pagina di dettaglio relativa alla scimmia selezionata:

Screenshot dei dettagli delle scimmie, in iOS e Android

Definire l'aspetto degli elementi dei risultati della ricerca

Oltre a visualizzare dati string nei risultati della ricerca, è possibile definire l'aspetto di ogni elemento dei risultati della ricerca impostando la proprietà SearchHandler.ItemTemplate su un oggetto DataTemplate:

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">    
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler Placeholder="Enter search term"
                                      ShowsResults="true">
            <controls:AnimalSearchHandler.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10"
                          ColumnDefinitions="0.15*,0.85*">
                        <Image Source="{Binding ImageUrl}"
                               HeightRequest="40"
                               WidthRequest="40" />
                        <Label Grid.Column="1"
                               Text="{Binding Name}"
                               FontAttributes="Bold"
                               VerticalOptions="Center" />
                    </Grid>
                </DataTemplate>
            </controls:AnimalSearchHandler.ItemTemplate>
       </controls:AnimalSearchHandler>
    </Shell.SearchHandler>
    ...
</ContentPage>

Il codice C# equivalente è il seguente:

Shell.SetSearchHandler(this, new AnimalSearchHandler
{
    Placeholder = "Enter search term",
    ShowsResults = true,
    ItemTemplate = new DataTemplate(() =>
    {
        Grid grid = new Grid { Padding = 10 };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.15, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.85, GridUnitType.Star) });

        Image image = new Image { HeightRequest = 40, WidthRequest = 40 };
        image.SetBinding(Image.SourceProperty, "ImageUrl");
        Label nameLabel = new Label { FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.Center };
        nameLabel.SetBinding(Label.TextProperty, "Name");

        grid.Children.Add(image);
        grid.Children.Add(nameLabel, 1, 0);
        return grid;
    })
});

Gli elementi specificati in DataTemplate definiscono l'aspetto di ogni elemento nell'area dei suggerimenti. In questo esempio il layout all'interno di DataTemplate è gestito da un oggetto Grid. Grid contiene un oggetto Image e un oggetto Label, entrambi associati alle proprietà di ogni oggetto Monkey.

Gli screenshot seguenti mostrano il risultato dell'applicazione di un modello per ogni elemento nell'area dei suggerimenti:

Screenshot dei risultati della ricerca basato su modelli in un gestore di ricerca shell, in iOS e Android

Per altre informazioni sui modelli di dati, vedere Xamarin.Forms Modelli di dati.

Visibilità della casella di ricerca

Per impostazione predefinita, quando un SearchHandler oggetto viene aggiunto nella parte superiore di una pagina, la casella di ricerca è visibile e completamente espansa. Tuttavia, questo comportamento può essere modificato impostando la proprietà SearchHandler.SearchBoxVisibility su uno dei membri dell'enumerazione SearchBoxVisibility:

  • Hidden: la casella di ricerca non è visibile o accessibile.
  • Collapsible: la casella di ricerca è nascosta fino a quando l'utente non esegue un'azione per visualizzarla. In iOS la casella di ricerca viene visualizzata rimbalzando verticalmente il contenuto della pagina e in Android la casella di ricerca viene visualizzata toccando l'icona del punto interrogativo.
  • Expanded: la casella di ricerca è visibile e completamente espansa. Questo è il valore predefinito per la proprietà SearchBoxVisibility.

Importante

In iOS una casella di ricerca collapsible richiede iOS 11 o versione successiva.

L'esempio seguente illustra come nascondere la casella di ricerca:

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler SearchBoxVisibility="Hidden"
                                      ... />
    </Shell.SearchHandler>
    ...
</ContentPage>

Stato attivo della casella di ricerca

Con il tocco in una casella di ricerca viene richiamata la tastiera su schermo e la casella di ricerca riceve lo stato attivo per l'input. È possibile ottenere questo comportamento anche a livello di programmazione chiamando il metodo Focus, che tenta di impostare lo stato attivo per l'input nella casella di ricerca e restituisce true in caso di esito positivo. Quando una casella di ricerca ottiene lo stato attivo, viene generato l'evento Focused e viene chiamato il metodo OnFocused che può essere sottoposto a override.

Quando lo stato attivo per l'input si trova in una casella di ricerca, se si tocca un'altra posizione sullo schermo la tastiera su schermo viene chiusa e la casella di ricerca perde lo stato attivo. È anche possibile ottenere questo comportamento a livello di programmazione chiamando il metodo Unfocus. Quando una casella di ricerca perde lo stato attivo, viene generato l'evento Unfocused e viene chiamato il metodo OnUnfocus che può essere sottoposto a override.

Lo stato attivo di una casella di ricerca può essere recuperato tramite la proprietà IsFocused, che restituisce true se lo stato attivo per l'input si trova in un SearchHandler.

Tastiera per SearchHandler

La tastiera che viene visualizzata quando gli utenti interagiscono con un SearchHandler può essere impostata a livello di programmazione tramite la proprietà Keyboard su una delle proprietà seguenti dalla classe Keyboard:

  • Chat - usata per messaggi di testo e posizioni in cui sono utili gli emoji.
  • Default - tastiera predefinita.
  • Email - usata per l'immissione di indirizzi di posta elettronica.
  • Numeric - usata per l'immissione di numeri.
  • Plain - usata per l'immissione di testo, senza KeyboardFlags specificati.
  • Telephone - usata per l'immissione di numeri di telefono.
  • Text - usata per l'immissione di testo.
  • Url - usata per l'immissione di percorsi di file e indirizzi Web.

Per ottenere questo risultato, è possibile procedere come segue in XAML:

<SearchHandler Keyboard="Email" />

Il codice C# equivalente è il seguente:

SearchHandler searchHandler = new SearchHandler { Keyboard = Keyboard.Email };

La classe Keyboard include anche un metodo factory Create che può essere usato per personalizzare una tastiera, specificando il comportamento di maiuscole/minuscole, controllo ortografico e suggerimenti. I valori di enumerazione KeyboardFlags vengono specificati come argomenti del metodo, con la restituzione di un elemento Keyboard personalizzato. L'enumerazione KeyboardFlags contiene i valori seguenti:

  • None - non vengono aggiunte funzionalità alla tastiera.
  • CapitalizeSentence - indica che la prima lettera della prima parola di ogni frase immessa verrà automaticamente scritta in maiuscolo.
  • Spellcheck - indica che verrà eseguito il controllo ortografico sul testo immesso.
  • Suggestions – indica che verranno offerti completamenti di parole per il testo immesso.
  • CapitalizeWord - indica che la prima lettera di ogni parola verrà automaticamente scritta in maiuscolo.
  • CapitalizeCharacter - indica che ogni carattere verrà scritto automaticamente in maiuscolo.
  • CapitalizeNone - indica che non verrà applicata automaticamente la conversione in maiuscolo.
  • All - indica che il controllo ortografico, i completamenti delle parole e la conversione in maiuscolo per le frasi verranno applicati al testo immesso.

L'esempio di codice XAML seguente mostra come personalizzare l'elemento Keyboard predefinito per offrire i completamenti delle parole e convertire in maiuscolo tutti i caratteri immessi:

<SearchHandler Placeholder="Enter search terms">
    <SearchHandler.Keyboard>
        <Keyboard x:FactoryMethod="Create">
            <x:Arguments>
                <KeyboardFlags>Suggestions,CapitalizeCharacter</KeyboardFlags>
            </x:Arguments>
        </Keyboard>
    </SearchHandler.Keyboard>
</SearchHandler>

Il codice C# equivalente è il seguente:

SearchHandler searchHandler = new SearchHandler { Placeholder = "Enter search terms" };
searchHandler.Keyboard = Keyboard.Create(KeyboardFlags.Suggestions | KeyboardFlags.CapitalizeCharacter);