Pesquisa do Shell do .NET MAUI
O Shell da interface do usuário do aplicativo .NET multiplataforma (.NET MAUI) inclui a SearchHandler funcionalidade de pesquisa integrada fornecida pela classe. O recurso de pesquisa pode ser adicionado a uma página definindo a propriedade anexada Shell.SearchHandler
a um objeto de SearchHandler subclasse. Isso faz com que uma caixa de pesquisa seja adicionada na parte superior da página:
Quando uma consulta é inserida na caixa de pesquisa, a propriedade Query
é atualizada e, em cada atualização, o método OnQueryChanged
é executado. Esse método pode ser substituído para preencher a área de sugestões de pesquisa com dados:
Em seguida, quando um resultado é selecionado na área de sugestões de pesquisa, o método OnItemSelected
é executado. Esse método pode ser substituído para responder apropriadamente, por exemplo, navegando para uma página de detalhes.
Criar um SearchHandler
A funcionalidade de pesquisa pode ser adicionada a um aplicativo Shell subclassificando a SearchHandler classe e substituindo os OnQueryChanged
métodos and 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);
Animal animal = item as Animal;
string navigationTarget = GetNavigationTarget();
if (navigationTarget.Equals("catdetails") || navigationTarget.Equals("dogdetails"))
{
// Navigate, passing a string
await Shell.Current.GoToAsync($"{navigationTarget}?name={((Animal)item).Name}");
}
else
{
string lowerCasePropertyName = navigationTarget.Replace("details", string.Empty);
// Capitalise the property name
string propertyName = char.ToUpper(lowerCasePropertyName[0]) + lowerCasePropertyName.Substring(1);
var navigationParameters = new Dictionary<string, object>
{
{ propertyName, animal }
};
// Navigate, passing an object
await Shell.Current.GoToAsync($"{navigationTarget}", navigationParameters);
}
}
string GetNavigationTarget()
{
return (Shell.Current as AppShell).Routes.FirstOrDefault(route => route.Value.Equals(SelectedItemNavigationTarget)).Key;
}
}
A substituição de OnQueryChanged
tem dois argumentos: oldValue
, que contém a consulta de pesquisa anterior, e newValue
, que contém a consulta de pesquisa atual. A área de sugestões de pesquisa pode ser atualizada, definindo-se a propriedade SearchHandler.ItemsSource
como uma coleção IEnumerable
que contém itens que correspondem à consulta de pesquisa atual.
Quando um resultado de pesquisa é selecionado pelo usuário, a substituição de OnItemSelected
é executada, e a propriedade SelectedItem
é definida. Nesse exemplo, o método navega para outra página que exibe os dados sobre o Animal
selecionado. Para obter mais informações sobre navegação, consulte Navegação do shell.
Observação
As propriedades SearchHandler adicionais podem ser definidas para controlar a aparência da caixa de pesquisa.
Criar um SearchHandler
A subclasse pode ser consumida SearchHandler definindo a propriedade anexada Shell.SearchHandler
para um objeto do tipo subclasse, na página de consumo:
<ContentPage ...
xmlns:controls="clr-namespace:Xaminals.Controls">
<Shell.SearchHandler>
<controls:AnimalSearchHandler Placeholder="Enter search term"
ShowsResults="true"
DisplayMemberName="Name" />
</Shell.SearchHandler>
...
</ContentPage>
Este é o código C# equivalente:
Shell.SetSearchHandler(this, new AnimalSearchHandler
{
Placeholder = "Enter search term",
ShowsResults = true,
DisplayMemberName = "Name"
});
O método AnimalSearchHandler.OnQueryChanged
retorna um List
de objetos Animal
. A propriedade DisplayMemberName
é definida como a propriedade Name
de cada objeto Animal
e, portanto, os dados exibidos na área de sugestões serão cada nome de animal.
Aviso
SearchHandler.DisplayMemberName
não é seguro para corte e não deve ser usado com corte completo ou NativeAOT. Em vez disso, você deve fornecer um ItemTemplate
para definir a aparência dos resultados SearchHandler
. Para obter mais informações, consulte Definir a aparência do item de resultados da pesquisa, Cortar um aplicativo .NET MAUI e Implantação de AOT nativa.
A propriedade ShowsResults
é definida como true
, de modo que as sugestões de pesquisa são exibidas enquanto o usuário insere uma consulta de pesquisa:
À medida que a consulta de pesquisa muda, a área de sugestões da pesquisa é atualizada:
Quando um resultado de pesquisa é selecionado, o MonkeyDetailPage
é navegado e uma página de detalhes sobre o macaco selecionado é exibida:
Definir a aparência do item dos resultados da pesquisa
Além de exibir os dados string
nos resultados da pesquisa, a aparência de cada item do resultado da pesquisa pode ser definida configurando a propriedade SearchHandler.ItemTemplate
como 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>
Os elementos especificados em DataTemplate definem a aparência de cada item na área de sugestões. Neste exemplo, o layout dentro do DataTemplate é gerenciado por um Grid. O Grid contém um objeto Image e um objeto Label, que se ligam a propriedades de cada objeto Monkey
.
A captura de tela a seguir mostra o resultado da modelagem de cada item na área de sugestões:
Para obter mais informações sobre modelos de dados, consulte Modelos de dados.
Visibilidade da caixa de pesquisa
Por padrão, quando a SearchHandler é adicionado na parte superior de uma página, a caixa de pesquisa fica visível e totalmente expandida. No entanto, esse comportamento pode ser alterado definindo a propriedade SearchHandler.SearchBoxVisibility
para um dos membros da enumeração SearchBoxVisibility
:
Hidden
– a caixa de pesquisa não está visível ou acessível.Collapsible
– a caixa de pesquisa está oculta até que o usuário execute uma ação para mostrá-la. No iOS, a caixa de pesquisa é revelada saltando verticalmente o conteúdo da página e, no Android, a caixa de pesquisa é revelada tocando no ícone de ponto de interrogação.Expanded
– a caixa de pesquisa está visível e totalmente expandida. Este é o valor padrão da propriedadeSearchBoxVisibility
.
Importante
No iOS, uma caixa de pesquisa recolhível requer o iOS 11 ou superior.
O exemplo a seguir mostra como ocultar a caixa de pesquisa:
<ContentPage ...
xmlns:controls="clr-namespace:Xaminals.Controls">
<Shell.SearchHandler>
<controls:AnimalSearchHandler SearchBoxVisibility="Hidden"
... />
</Shell.SearchHandler>
...
</ContentPage>
Foco na caixa de pesquisa
Tocar na caixa de pesquisa invoca o teclado na tela, e a caixa de pesquisa recebe o foco de entrada. Isso também pode ser feito de forma programática chamando o método Focus
, que tenta definir o foco de entrada na caixa de pesquisa e retornará true
se for bem-sucedido. Quando o foco passa para a caixa de pesquisa, o evento Focused
é acionado, e o método OnFocused
substituível é chamado.
Quando o foco de entrada estiver em uma caixa de pesquisa, tocar em qualquer parte da tela fará o teclado na tela desaparecer e a caixa de pesquisa perder o foco de entrada. Isso também poderá ser feito de forma programática chamando o método Unfocus
. Quando a caixa de pesquisa perde o foco, o evento Unfocused
é acionado, e o método OnUnfocus
substituível é chamado.
O estado do foco de uma caixa de pesquisa poderá ser recuperado por meio da propriedade IsFocused
, que retornará true
se um SearchHandler estiver com o foco de entrada no momento.
Teclado do SearchHandler
O teclado que é exibido quando um usuário interage com um SearchHandler pode ser definido de forma programática por meio da propriedade do Keyboard
, para uma das seguintes propriedades da classe Keyboard
:
Chat
– usado para mensagens de texto e lugares em que os emojis são úteis.Default
– o teclado padrão.Email
– usado ao inserir endereços de email.Numeric
– usado ao inserir números.Plain
– usado ao inserir texto, sem nenhumKeyboardFlags
especificado.Telephone
– usado ao inserir números de telefone.Text
– usado ao inserir texto.Url
– usado para inserir caminhos de arquivos e endereços web.
Isso pode ser feito no XAML da seguinte maneira:
<SearchHandler Keyboard="Email" />
A classe Keyboard
também tem um método de fábrica Create
que pode ser usado para personalizar um teclado especificando o comportamento de capitalização, de verificação ortográfica e de sugestão. Os valores de enumeração KeyboardFlags
são especificados como argumentos para o método, e um Keyboard
personalizado é retornado. A enumeração KeyboardFlags
contém os seguintes valores:
None
– nenhum recurso é adicionado ao teclado.CapitalizeSentence
– indica que as primeiras letras das primeiras palavras de cada frase serão automaticamente maiúsculas.Spellcheck
– indica que a verificação ortográfica será executada no texto digitado.Suggestions
– indica que os preenchimentos de palavra sugerida será realizado no texto digitado.CapitalizeWord
– indica que a primeira letra de cada palavra será automaticamente maiúscula.CapitalizeCharacter
– indica que todos os caracteres serão automaticamente colocados em maiúsculas.CapitalizeNone
– indica que não ocorrerá nenhuma capitalização automática ocorrerá.All
– indica que a verificação ortográfica, os preenchimentos de palavra sugerida e a capitalização de frases ocorrerão no texto digitado.
O seguinte exemplo de código XAML mostra como personalizar o Keyboard
padrão para oferecer preenchimentos de palavra sugerida e capitalizar todos os caracteres inseridos:
<SearchHandler Placeholder="Enter search terms">
<SearchHandler.Keyboard>
<Keyboard x:FactoryMethod="Create">
<x:Arguments>
<KeyboardFlags>Suggestions,CapitalizeCharacter</KeyboardFlags>
</x:Arguments>
</Keyboard>
</SearchHandler.Keyboard>
</SearchHandler>