Поделиться через


Поиск оболочки .NET MAUI

Просмотрите пример. Обзор примера

Оболочка многоплатформенного приложения .NET (.NET MAUI) включает интегрированные функции поиска, предоставляемые классом SearchHandler . Возможность поиска можно добавить на страницу, указав для присоединенного свойства Shell.SearchHandler в качестве значения объект подкласса SearchHandler. После этого в верхней части страницы появится поле поиска:

Снимок экрана: оболочка SearchHandler.

При вводе запроса в поле поиска обновляется свойство Query, а при каждом обновлении выполняется метод OnQueryChanged. Этот метод может быть переопределен для заполнения данными области поисковых подсказок:

Снимок экрана: результаты поиска в оболочке SearchHandler.

При выборе результата из области поисковых подсказок выполняется метод OnItemSelected. Этот метод может быть переопределен, чтобы вызвать соответствующую реакцию, например переход на страницу подробных сведений.

Создание SearchHandler

Функции поиска можно добавить в приложение Оболочки, подклассив SearchHandler класс и переопределив OnQueryChanged методы: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 app.
        await Shell.Current.GoToAsync($"{GetNavigationTarget()}?name={((Animal)item).Name}");
    }

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

Переопределение OnQueryChanged имеет два аргумента: oldValue содержит предыдущий поисковый запрос, а newValue — текущий поисковый запрос. Область поисковых подсказок можно обновлять, задавая свойству SearchHandler.ItemsSource значение коллекции IEnumerable с элементами, которые соответствуют текущему поисковому запросу.

Когда пользователь выбирает результат поиска, выполняется переопределение метода OnItemSelected и присваивается значение свойству SelectedItem. В нашем примере этот метод переходит на другую страницу, которая отображает данные о выбранных Animal. Дополнительные сведения о навигации см. в разделе Навигация по оболочке .

Примечание.

Дополнительные свойства SearchHandler позволяют управлять внешним видом поля поиска.

Использование SearchHandler

Подкласс SearchHandler можно использовать, присваивая присоединенному свойству Shell.SearchHandler значение объекта соответствующего типа на странице использования:

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

Эквивалентный код на C# выглядит так:

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

Метод AnimalSearchHandler.OnQueryChanged возвращает List объектов Animal. Свойству DisplayMemberName присваивается свойство Name каждого объекта Animal, а значит, отображаемые в области поисковых подсказок данные будут содержать названия каждого животного.

Предупреждение

SearchHandler.DisplayMemberName не является безопасным и не следует использовать с полной обрезкой или NativeAOT. Вместо этого необходимо указать внешний ItemTemplate SearchHandler вид результатов. Дополнительные сведения см. в разделе Определение внешнего вида элемента результатов поиска, обрезка приложения .NET MAUI и развертывания Собственного AOT.

Свойству ShowsResults присваивается значение true, чтобы поисковые подсказки отображались по мере ввода поискового запроса пользователем:

Снимок экрана: результаты поиска в оболочке SearchHandler с результатами частичной строки M.

По мере изменения поискового запроса данные в области поисковых подсказок обновляются:

Снимок экрана: результаты поиска в оболочке SearchHandler с результатами для частичной строки M o n.

При выборе результата поиска происходит переход к MonkeyDetailPage и отображается страница сведений о выбранной обезьяне:

Снимок экрана: сведения о обезьяне.

Определения внешнего вида элементов в результатах поиска

Помимо отображения данных string в результатах поиска, вы можете изменить внешний вид каждого элемента результатов поиска, присвоив свойству SearchHandler.ItemTemplate значение 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>

Указанные в DataTemplate элементы определяют внешний вид каждого элемента в области поисковых подсказок. В нашем примере компоновка внутри DataTemplate определяется значением Grid. Grid содержит объект Image и объект Label, оба из которых содержат привязки к свойствам каждого объекта Monkey.

На следующем снимке экрана показан результат создания шаблонов каждого элемента в области предложений:

Снимок экрана: результаты шаблонного поиска в оболочке SearchHandler.

Дополнительные сведения о шаблонах данных см. в разделе "Шаблоны данных".

Видимость поля поиска

Когда в верхней части страницы добавляется SearchHandler, поле поиска по умолчанию является видимым и полностью развернутым. Тем не менее это поведение можно изменить, задав в свойстве SearchHandler.SearchBoxVisibility один из членов перечисления SearchBoxVisibility:

  • Hidden — поле поиска не отображается и недоступно;
  • Collapsible — поле поиска является скрытым, пока пользователь не выполнит действие, открывающее его; Для отображения поля поиска в iOS нужно инициировать "подпрыгивание" содержимого страницы в вертикальном направлении, а в Android — коснуться значка вопросительного знака.
  • Expanded — поле поиска является видимым и полностью развернутым. Это значение по умолчанию для свойства SearchBoxVisibility.

Внимание

В iOS для свертываемого поля поиска требуется iOS 11 или более поздней версии.

В следующем примере показано, как скрыть поле поиска:

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

Фокус поля поиска

При касании поля поиска отображается экранная клавиатура, а в поле поиска появляется фокус ввода. Это можно также реализовать программным образом, вызвав метод Focus, который пытается задать фокус ввода в поле поиска и возвращает true при успешном выполнении. Когда поле поиска получает фокус, активируется событие Focused и вызывается переопределяемый метод OnFocused.

Когда в поле поиска есть фокус ввода, касание экрана в любом другом месте скрывает экранную клавиатуру и поле теряет фокус ввода. Это можно также реализовать программным образом, вызвав метод Unfocus. Когда поле поиска теряет фокус, активируется событие Unfocused и вызывается переопределяемый метод OnUnfocus.

Состояние фокуса в поле поиска можно получить с помощью свойства IsFocused, которое возвращает true, если SearchHandler в этот момент имеет фокус ввода.

Клавиатура SearchHandler

Клавиатуру, отображаемую при взаимодействии пользователя с SearchHandler, можно задать программно с помощью свойства Keyboard, используя следующие свойства класса Keyboard:

  • Chat — это текстовая клавиатура с эмодзи.
  • Default — это клавиатура по умолчанию.
  • Email используется для ввода адресов электронной почты.
  • Numeric — цифровая клавиатура.
  • Plain предназначена для ввода текста, если нет заданных KeyboardFlags.
  • Telephone — клавиатура для ввода телефонных номеров.
  • Text — текстовая клавиатура.
  • Url — клавиатура для ввода путей к файлам и веб-адресов.

Это можно сделать в XAML следующим образом:

<SearchHandler Keyboard="Email" />

Класс Keyboard также имеет фабричный метод Create, который может использоваться для настройки клавиатуры, задавая регистр букв, проверку орфографии и режим подсказок. Значения перечисления KeyboardFlags задаются как аргументы метода, при этом возвращается настроенное свойство Keyboard. Перечисление KeyboardFlags имеет такие значения:

  • None указывает, что клавиатура не имеет никаких дополнительных функций.
  • CapitalizeSentence указывает, что первые слова во всех вводимых предложениях автоматически начинаются с прописных букв.
  • Spellcheck указывает, что для вводимого текста выполняется проверка орфографии.
  • Suggestions указывает, что для вводимых слов предлагается завершение.
  • CapitalizeWord указывает, что все слова автоматически начинаются с прописных букв.
  • CapitalizeCharacter указывает, что все символы автоматически пишутся прописными буквами.
  • CapitalizeNone указывает, что автоматическая подстановка прописных букв не выполняется.
  • All указывает, что для вводимого текста выполняется проверка орфографии, завершение слов и автоматическое написание предложений с прописной буквы.

В следующем примере кода XAML показано, как настроить значение по умолчанию Keyboard, чтобы включить предложение завершения слов и написание всех символов прописными буквами:

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