Enabling & Working With Windows Search Feature in Windows Store Apps


You must have observed the new Windows Search Charm introduced by Microsoft in Windows 8 and onward versions. You can get this search charm for your help right away by pressing the Windows Key ( ) and "S" key together in other words + S keystrokes. Most of the Windows app developers will be contemplating methods to implement the same Windows Search Charm feature customized to their application. Introducing the new search charm customized to your Windows Store App for app users can be done by following this article and applying the changes to your Windows Store App.

In this document, I have taken a very basic scenario with regard to the Windows Store App. The main page will have a button named “Search” at the center of the page. When you press the “Search” button, a Search Charm restricted to your Windows Store App will appear. The search charm is a search tool that provides suitable suggestions (query suggestions and requested suggestions) recommended for the application within the search pane.

Step 1: Create a Windows Store App project then drag and drop a button control upon the designer view of the main page from the pre-populated toolbox list.

Screen shot of design view

Figure 1: Screen shot of design view of main page with button named “Search”.

Double-click on the button results so as to generate a button click event handler. Upon click of this “Search” button, we will execute the code that gives us the Search Charm.

Step 2: Using the SearchPane class to make use of the Search feature in your Windows Store App.

The SearchPane helps in the management of the search pane by the result of the search charm activation done by the user.

Search Pane

Figure 2: Class Diagram of SearchPane class.

In this class (as shown in the preceding class diagram: Figure 2), I am more concerned about GetForCurrentView( ) method because this is a method that fetches us instances of the search pane upon a user's search.

  1. SearchPane.GetForCurrentView().Show(); 

The preceding line of code makes the search pane displayed on the screen and thereby makes it available to the user using the Windows Store App.

Step 3: Registering the app as the search provider by adding a “Search” declaration to enable search charm capabilities.

  • Click on the Package.appxmanifest designer.

    Solution Explorer

    Figure: Highlighting the Package.appxmanifest designer file present under the project in the Solution Explorer.
  • Go to the “Declarations” tab and select the “search” option from the dropdown.

    Manifest File

    Figure 3: Selecting the “search” option from the Available Declarations dropdown in the Declarations tab.
  • Adding “search” to the Supported Declarations.

    Supported Declaration

    Figure 4: After adding the “search” option to the Supported Declarations.

Step 4: Creating and displaying the search pane upon clicking the “Search” button present in the main page.

  • Add the namespace in the code to use the Windows Search Charm:
    1. using Windows.ApplicationModel.Search; 
  • Trigger SuggestionsRequested event upon a user's search.
  • Trigger ResultSuggestionChosen event when the user selects one of the results displayed in the search pane.

The code present inside the method present within the button click event handler is presented below:

  1. SearchPane.GetForCurrentView().SuggestionsRequested += MainPage_SuggestionsRequested;  
  2. SearchPane.GetForCurrentView().ResultSuggestionChosen += MainPage_ResultSuggestionChosen;  
  3. SearchPane.GetForCurrentView().Show(); 

Step 5: Writing the code inside the method (in other words Event Handler) associated with the SuggestionsRequested event.

Once you type SearchPane.GetForCurrentView().SuggestionsRequested+= , press the Tab keystroke twice so that it will generate a method associated with the SuggestionsRequested event that is necessary to handle this event. Post this, move to this method and write the necessary code that provides suggestions and results fetched by the search charm depending on the user's entry in the search field. The entire code is placed below:

  1. void MainPage_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)  
  2. {  
  3.     var listOfSuggestions = args.Request.SearchSuggestionCollection;  
  4.     if(listOfSuggestions.Size==0)  
  5.     {  
  6.         listOfSuggestions.AppendQuerySuggestion("Apple");  
  7.         listOfSuggestions.AppendQuerySuggestion("Avocado");  
  8.         listOfSuggestions.AppendQuerySuggestion("Apricot");         
  9.         listOfSuggestions.AppendSearchSeparator("Fruit Seperator");         
  10.         listOfSuggestions.AppendResultSuggestion("AppleDetails",  
  11.         detailText: "Kashmiri Apples",  
  12.         tag: "AboutApple",  
  13.         image: RandomAccessStreamReference.CreateFromUri(  
  14.         new Uri("http://www.websitename/apple.png")),  
  15.         // image:RandomAccessStreamReference.CreateFromFile(file),  
  16.         imageAlternateText: "Apples");         
  17.     }     

The code above shows the event handler associated with the SuggestionsRequested event. As shown in the code above, the SearchPaneSuggestionsRequest sealed class has a property SearchSuggestionCollection that is of the same type as the SearchSuggestionCollection class. In the preceding piece of code, the if(listOfSuggestions.Size==0) condition has been used to ensure that re-insertion of duplicate data will not occur in the scenario of reinsertion of the suggestions multiple times within the “listOfSuggestions” variable (each time when the SuggestionsRequested event is triggered). We can use “args.QueryText” that helps to fetch the actual query text entered within the search box by the user.

SearchPane Suggesstion

Figure 5: SearchPaneSuggestionsRequestedEventArgs class diagram.

In the preceding class the “Request” property is of type SearchPaneSuggestionsRequest. The SearchSuggestionCollection class helps in adding various search suggestions (including query suggestions, result suggestion, search separator) for the search pane.

 Searh Suggesstion

Figure 6: Class diagram of SearchSuggestionCollection class.

As shown in the preceding class diagram as well as with respect to my addition in the code, AppendQuerySuggestion helps in adding a Query Suggestion as shown in the following screen (Figure 7). AppendQuerySuggestions aids the user's search efficiency by helping him add up multiple query suggestions as search pane entries. AppendResultSuggestion helps in adding Result Suggestion for the search pane. AppendSearchSeperator helps in adding a Search Separator for the search pane. Query Suggestion, Search Separator and Result Suggestion are all shown in the following figure (Figure 7). The following screen shows an example illustration of this feature.

Search Charm

Figure 7: Screen shows the results of the sample Search Charm demo code.

We can customize this by putting if and else-if statements to restrict the search results to specific letters.

  1. void MainPage_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)  
  2. {  
  3.     var listOfSuggestions = args.Request.SearchSuggestionCollection;  
  4.     if (listOfSuggestions.Size == 0)  
  5.     {  
  6.         if (args.QueryText.StartsWith("a", StringComparison.CurrentCultureIgnoreCase))  
  7.         {  
  8.             listOfSuggestions.AppendQuerySuggestion("Apple");  
  9.             listOfSuggestions.AppendQuerySuggestion("Avocado");  
  10.             listOfSuggestions.AppendQuerySuggestion("Apricot");  
  11.             listOfSuggestions.AppendSearchSeparator("Fruit Separator");  
  12.             listOfSuggestions.AppendResultSuggestion("AppleDetails",  
  13.             detailText: "Kashmiri Apples",  
  14.             tag: "AboutApple",  
  15.             image: RandomAccessStreamReference.CreateFromUri(  
  16.             new Uri("http://www.websitename/apple.png")),  
  17.             // image:RandomAccessStreamReference.CreateFromFile(file),  
  18.             imageAlternateText: "Apples");  
  19.         }  
  21.         else if (args.QueryText.StartsWith("b", StringComparison.CurrentCultureIgnoreCase))  
  22.         {  
  23.             listOfSuggestions.AppendQuerySuggestion("Black Berry");  
  24.             listOfSuggestions.AppendQuerySuggestion("Blue Berry");  
  25.             listOfSuggestions.AppendQuerySuggestion("Beach Plum");  
  26.         }  
  27.         // put else-if for rest 25 alphabets i.e. C-Z.  
  28.     }  
  29. }  

When you execute the application that has the preceding piece of code, it shows how a search can be restricted depending on the query text's first letter.

Searching Pane

Figure 8: Screen shows search results restricted to specific letters upon user's input. Here, it is the letter "b".

Searching Pane Desc

Figure 9: Illustration of the structure of the Result Suggestion that appeared in the search pane along with annotation of its fields.

  1. listOfSuggestions.AppendResultSuggestion("Berry",  
  2. detailText: "India Berries",  
  3. tag: "About Berry",  
  4. image: RandomAccessStreamReference.CreateFromUri(  
  5. new Uri("http://www.websitename/berry.png")),  
  6. // image:RandomAccessStreamReference.CreateFromFile(file),  
  7. imageAlternateText: "Berry"); 

Compare the preceding piece of code to add a new result suggestion with the preceding screen that reflects the output. With this comparison, it is very clear that only text, detail text and an image will appear in the output of the result suggestion upon a search. Whereas the "tag" will not appear within the search pane.

Main Page Code

The preceding code shows that the addition of the Windows.Storage.Streams namespace in the code is necessary since the RandomAccessStreamReference class is in this namespace.

Step 6: Writing code inside the method (the Event Handler) associated with the ResultSuggestionChosen event.

  1. void MainPage_ResultSuggestionChosen(SearchPane sender, SearchPaneResultSuggestionChosenEventArgs args)  
  2. {  
  3.     // args.Tag will contain the selected Tag.  
  4.     var selectedTag = args.Tag;  
  5.     //Write the code to open the file with respect to the selected Tag