共用方式為


Xamarin.Forms 殼層搜尋

Xamarin.Forms Shell 包含 類別所提供的 SearchHandler 整合式搜尋功能。 將附加屬性設定 Shell.SearchHandler 為子類別 SearchHandler 化物件,即可將搜尋功能新增至頁面。 這會使搜尋方塊新增至頁面頂端:

iOS 和 Android 上 Shell SearchHandler 的螢幕快照

當在搜尋方塊中輸入查詢時,便會更新 Query 屬性,並在每次更新時執行 OnQueryChanged 方法。 可以覆寫此方法,以使用資料填入搜尋建議區域:

iOS 和 Android 上 Shell SearchHandler 中搜尋結果的螢幕快照

然後,當從建議區域選取結果時,就會執行 OnItemSelected 方法。 可以覆寫此方法以做出適當回應,例如透過導覽至詳細資料頁面。

建立 SearchHandler

SearchHandler 類別子類別化,並覆寫 OnQueryChangedOnItemSelected 方法,就可以將搜尋功能新增至 Shell 應用程式:

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;
    }
}

OnQueryChanged 覆寫有兩個引數:oldValue 中包含先前的搜尋查詢,而 newValue 中則包含目前的搜尋查詢。 將 SearchHandler.ItemsSource 屬性設為其中包含符合目前搜尋查詢之項目的 IEnumerable 集合,就可以更新搜尋建議區域。

當使用者選取搜尋結果時,會執行 OnItemSelected 覆寫並設定 SelectedItem 屬性。 在此範例中,此方法會導覽至顯示所選 Animal 相關資料的另一個頁面。 如需流覽的詳細資訊,請參閱 Xamarin.Forms 殼層流覽

注意

您可以設定其他 SearchHandler 屬性來控制搜尋方塊的外觀。

取用 SearchHandler

在取用頁面上,將附加屬性設定Shell.SearchHandler為子類別化類型的物件,即可取用子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 方法會傳回 Animal 物件的 ListDisplayMemberName 屬性會設定為每個 Animal 物件的 Name 屬性,因此,建議區域中顯示的資料將會是每個動物名稱。

ShowsResults 屬性會設定為 true,因此在使用者輸入搜尋查詢時,便會顯示搜尋建議:

iOS 和 Android 上 Shell SearchHandler 中搜尋結果的螢幕快照,其中包含部分字串 M 的結果。

當搜尋查詢變更時,就會更新搜尋建議區域:

iOS 和 Android 上 Shell SearchHandler 中搜尋結果的螢幕快照,其中包含部分字串 M o n 的結果。

選取搜尋結果時, MonkeyDetailPage 會巡覽至 ,並顯示所選猴子的詳細數據頁面:

iOS 和 Android 上猴子詳細數據的螢幕快照

定義搜尋結果項目外觀

除了顯示搜尋結果中的 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>

對等的 C# 程式碼為:

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;
    })
});

DataTemplate 中指定的元素會定義建議區域中每個項目的外觀。 在此範例中,DataTemplate 內的版面配置受 Grid 管理。 Grid 包含一個 Image 物件和一個 Label 物件,這兩個物件都會繫結至每個 Monkey 物件的屬性。

下列螢幕擷取畫面顯示建議區域中,每個項目的範本結果:

iOS 和 Android 上 Shell SearchHandler 中樣板化搜尋結果的螢幕快照

如需數據範本的詳細資訊,請參閱 Xamarin.Forms 數據範本

搜尋方塊的可見性

根據預設,在 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 屬性擷取搜尋方塊的焦點狀態,如果 SearchHandler 目前具有輸入焦點,則傳回 true

SearchHandler 鍵盤

使用者與 SearchHandler 互動時顯示的鍵盤,可以透過 Keyboard 屬性以程式設計方式設定為 Keyboard 類別中的下列屬性之一:

  • Chat - 用於收發簡訊和 Emoji 有用的地方。
  • Default - 預設鍵盤。
  • Email - 輸入電子郵件地址時使用。
  • Numeric - 輸入數字時使用。
  • Plain - 輸入文字時使用,不指定任何 KeyboardFlags
  • Telephone - 輸入電話號碼時使用。
  • Text - 輸入文字時使用。
  • Url - 用於輸入檔案路徑與網址。

執行下列工作即可用 XAML 來達成這點:

<SearchHandler Keyboard="Email" />

對等的 C# 程式碼為:

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

Keyboard 類別還具有 Create Factory 方法,可透過指定大小寫、拼字檢查和建議的行為來自訂鍵盤。 KeyboardFlags 列舉值會被指定為方法的引數,並傳回自訂的 KeyboardKeyboardFlags 列舉包含下列值:

  • 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>

對等的 C# 程式碼為:

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