首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 Store Apps 搜尋合約完整指南:本地建議、遠端建議、檔案屬性搜尋與 IME 整合

     編輯:關於.NET

前言

搜尋合約讓應用整合至系統層級的搜尋體驗:使用者在任意處呼叫搜尋 Charm,輸入關鍵字即可搜尋應用內容。Windows 8 提供豐富的建議機制:本地靜態建議、遠端動態建議(含圖示/描述)、本地檔案屬性索引建議,並支援輸入法編輯器 (IME) 協作。本文完整實作各類搜尋建議與搜尋啟動處理。

搜尋合約核心架構

類別角色關鍵成員
SearchPane搜尋面板存取點GetForCurrentView()、Show()、PlaceholderText、SearchHistoryEnabled/Context、ShowOnKeyboardInput、QueryChanged/QuerySubmitted/SuggestionsRequested/ResultSuggestionChosen/VisibilityChanged
SearchPaneSuggestionsRequest建議請求處理器SearchSuggestionCollection、AppendQuerySuggestion/AppendQuerySuggestions/AppendResultSuggestion/AppendSearchSeparator、GetDeferral()
SearchPaneQueryLinguisticDetailsIME 輸入法細節QueryTextAlternatives、QueryTextCompositionStart/Length
LocalContentSuggestionSettings本地檔案索引建議設定Enabled、Locations、AqsFilter、PropertiesToMatch

基礎整合:註冊與搜尋啟動

Package.appxmanifest 宣告

在「宣告」頁籤新增「搜尋」宣告,系統自動將應用加入搜尋來源清單。

App.xaml.cs 處理搜尋啟動


protected override void OnSearchActivated(SearchActivatedEventArgs args) {
    if (args.PreviousExecutionState == ApplicationExecutionState.Running) return;
    
    var rootFrame = new Frame();
    rootFrame.Navigate(typeof(MainPage), args); // 攜帶查詢文字
    Window.Current.Content = rootFrame;
    Window.Current.Activate();
}

頁面初始化 SearchPane


protected override void OnNavigatedTo(NavigationEventArgs e) {
    _searchPane = SearchPane.GetForCurrentView();
    _searchPane.QueryChanged += OnQueryChanged;
    _searchPane.QuerySubmitted += OnQuerySubmitted;
    _searchPane.PlaceholderText = "請輸入關鍵字";
    _searchPane.SearchHistoryEnabled = true;
    _searchPane.SearchHistoryContext = "user_search"; // 區分不同搜尋情境的歷史
    _searchPane.ShowOnKeyboardInput = true; // 直接輸入即喚出搜尋面板
    
    // 若由搜尋啟動,取得查詢文字
    var args = e.Parameter as SearchActivatedEventArgs;
    if (args != null) ShowSearchPane(args.QueryText);
}

private void ShowSearchPane(string query = "") {
    _searchPane.Show(query);
}

本地靜態建議:SuggestionsRequested + 靜態清單

適用於固定詞彙庫(城市、產品代碼、標籤等),無需網路請求:


private static readonly string[] _cityList = { 
    "beijing", "北京", "beiji", "北極", 
    "shanghai", "上海", "tianjin", "天津", 
    "chongqing", "重慶" 
};

private void OnSuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args) {
    if (string.IsNullOrEmpty(args.QueryText)) return;
    
    // 1. 根據 IME 輸入法候選字串篩選
    foreach (var alt in args.LinguisticDetails.QueryTextAlternatives) {
        foreach (var city in _cityList) {
            if (city.StartsWith(alt, StringComparison.CurrentCultureIgnoreCase)) {
                args.Request.SearchSuggestionCollection.AppendQuerySuggestion(city);
                if (args.Request.SearchSuggestionCollection.Size >= 5) return;
            }
        }
    }
    
    // 2. 根據直接輸入文字篩選
    foreach (var city in _cityList) {
        if (city.StartsWith(args.QueryText, StringComparison.CurrentCultureIgnoreCase)) {
            args.Request.SearchSuggestionCollection.AppendQuerySuggestion(city);
            if (args.Request.SearchSuggestionCollection.Size >= 5) return;
        }
    }
}

關鍵點: QueryTextAlternatives 包含 IME 當前所有候選文字(如拼音輸入中「beij」對應「北京」「北極」),針對每個候選詞篩選可大幅提升中文輸入體驗。

遠端動態建議:非同步請求 + 圖文豐富建議

適用於即時搜尋建議(電商商品、地址自動完成),支援圖示、描述、分隔線:


private HttpClient _httpClient = new HttpClient();
private Task _currentRequest;

private async void OnSuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args) {
    var deferral = args.Request.GetDeferral(); // 開始異步操作
    try {
        // 取消上一個未完成請求
        if (_currentRequest != null) _currentRequest.AsAsyncOperation().Cancel();
        
        // 發起新請求(範例:淘寶建議 API)
        _currentRequest = _httpClient.GetStringAsync(
            $"https://suggest.taobao.com/sug?extras=1&code=utf-8&q={args.QueryText}");
        string response = await _currentRequest;
        
        var json = JsonObject.Parse(response);
        var array = json["result"].GetArray();
        
        foreach (var item in array) {
            string suggestion = item.GetArray()[0].GetString();
            // AppendResultSuggestion:文字 + 描述 + 標籤 + 圖示 + 替代文字
            args.Request.SearchSuggestionCollection.AppendResultSuggestion(
                suggestion, "描述文字", suggestion,
                RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Logo.png")),
                "替代文字"
            );
            args.Request.SearchSuggestionCollection.AppendSearchSeparator("分隔線");
            
            if (args.Request.SearchSuggestionCollection.Size >= 5) break;
        }
    } finally {
        deferral.Complete(); // 完成異步操作
    }
}

private void OnResultSuggestionChosen(SearchPane sender, SearchPaneResultSuggestionChosenEventArgs args) {
    // 使用者點選圖文建議項(非純文字查詢)
    lblStatus.Text = $"選中建議: {args.Tag}";
}

private void OnQuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args) {
    // 使用者提交純文字查詢(Enter 或點選純文字建議)
    lblStatus.Text = $"提交查詢: {args.QueryText}";
}

關鍵差異:

  • AppendQuerySuggestion:純文字建議,使用者點選觸發 QuerySubmitted
  • AppendResultSuggestion:豐富建議(文字+描述+圖示),使用者點選觸發 ResultSuggestionChosen,攜帶 Tag 參數
  • GetDeferral()/Complete():非同步建議獲取必須配對使用

本地檔案屬性建議:LocalContentSuggestionSettings

利用 Windows 索引器搜尋檔案中繼資料(標題、作者、標籤等),無需自行索引:


protected override void OnNavigatedTo(NavigationEventArgs e) {
    var settings = new LocalContentSuggestionSettings {
        Enabled = true,
        Locations = { KnownFolders.MusicLibrary }, // 需 Manifest 勾選「音樂庫」能力
        AqsFilter = "kind:music", // AQS 查詢語法,限定音樂類型
        PropertiesToMatch = { 
            "System.Title", "System.Music.Artist", "System.Music.AlbumTitle" 
        }
    };
    SearchPane.GetForCurrentView().SetLocalContentSuggestionSettings(settings);
}

AQS (Advanced Query Syntax) 範例:

  • kind:music、kind:picture、kind:document
  • type:.mp3、type:.jpg
  • author:"張三"、title:"報告"
  • 組合:kind:music author:"周杰倫"

前置條件: Manifest 勾選對應 Library 能力(音樂庫、圖片庫、文件庫等),檔案需經系統索引器掃描。

事件完整流程圖

使用者開啟搜尋 Charm
        ↓
SearchPane.Visible = true → VisibilityChanged 事件
        ↓
使用者輸入文字(鍵盤/IME)
        ↓
ShowOnKeyboardInput = true → 自動 Show()
        ↓
文字變化 → QueryChanged 事件(即時回饋)
        ↓
系統觸發 SuggestionsRequested 事件
        ↓
應用異步獲取建議 → AppendQuerySuggestion / AppendResultSuggestion
        ↓
建議顯示於搜尋面板下方(最多 5 項)
        ↓
使用者操作:
  ├─ 選擇純文字建議 → QuerySubmitted (QueryText)
  ├─ 選擇圖文建議 → ResultSuggestionChosen (Tag)
  └─ 直接按 Enter → QuerySubmitted (QueryText)
        ↓
應用處理查詢 → 顯示搜尋結果頁面
        ↓
SearchPane.Visible = false → VisibilityChanged 事件

最佳實踐與避坑

  1. 歷史記錄上下文: 不同搜尋情境(商品搜尋 vs 文章搜尋)設定不同 SearchHistoryContext,避免歷史混雜。
  2. IME 支援: 必須處理 QueryTextAlternatives,中文/日文/韓文輸入體驗才完整。
  3. 建議數量限制: 系統最多顯示 5 項,超過部分自動截斷,邏輯中需 Size >= 5 判斷提前退出。
  4. 遠端請求取消: 每次輸入變化取消上一個請求(Cancel()),避免舊回應覆蓋新結果(競態條件)。
  5. 異步建議 Deferral: GetDeferral() 必須在同步程式碼中呼叫,Complete() 在 finally 區塊確保釋放。
  6. ResultSuggestion Tag: 設計有意義的 Tag(如商品 ID、實體 ID),ResultSuggestionChosen 中直接導航至詳情頁。
  7. 本地檔案建議: 需 Manifest 能力宣告 + 系統索引器已掃描,首次部署可能無結果需等待索引完成。
  8. 查詢提交處理: QuerySubmitted 統一導航至搜尋結果頁,攜帶 QueryText 參數。

搜尋合約 vs 應用內搜尋框

  • 維度搜尋合約應用內搜尋框
    進入點系統 Charm (Win+Q)應用 UI 內部
    可見性全系統應用可被搜尋僅應用內部
    建議來源系統統一面板自行實作下拉/彈出
    適用場景內容導向型應用(新聞、電商、文件)工具型、社交型、高度自訂搜尋邏輯
    實作複雜度中(需處理啟動、建議、生命週期)低(完全自主控制)

    完整實作搜尋合約,能讓你的應用內容無縫接入 Windows 8 系統級搜尋體驗,大幅提升內容可發現性與使用者進入效率。

    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved