Autosuggestions are a great way to enhance user experience. The typical use case is where, whenever a user enters some text into a text field, a list of suggested words is displayed.
If you have not already done so, sign up for the Bing Autosuggest API at https://portal.azure.com.
As textboxes in WPF do not contain any autosuggestion features, we need to add some on our own. We are going to use a third-party package, so install the WPFTextBoxAutoComplete
package through the NuGet package manager, in our example project.
In the MainView.xaml
file, add the following attribute to the starting Window
tag:
xmlns:behaviors="clr-namespace: WPFTextBoxAutoComplete;assembly=WPFTextBoxAutoComplete"
We will also need to make sure that the TextBox
binding for our search query updates whenever the user enters data. This can be done by making sure that the Text
attribute looks as follows:
Text="{Binding SearchQuery, UpdateSourceTrigger=PropertyChanged}"
In the same TextBox
element, add the following:
behaviors:AutoCompleteBehavior.AutoCompleteItemsSource = "{Binding Suggestions}"
In the ViewModel, in the MainViewModel.cs
file, we need the corresponding property. This should be an IEnumerable<string>
object. This will be updated with the result from the autosuggest query we will perform presently.
To get autosuggestions, we first add a new class. Add a new file called BingAutoSuggest.cs
, to the Model
folder. The BingAutoSuggest
class should have a member of type BingWebRequest
, which should be created in the constructor.
Create a new function called Suggest
. This should accept a string
as a parameter, returning a Task<List<string>>
object. Mark the function as async
.
We will start by constructing an endpoint, where we specify the query string, q
. This field is required. We also specify the market, mkt
, although this is not required. We do not need any other parameters. Before we execute the API call, we will create a list of suggestions, which we will return to the caller:
public async Task<List<string>> Suggest(string query) { string endpoint = string.Format("{0}{1}&mkt=en-US", "https://api.cognitive.microsoft.com/bing/v7.0/suggestions/?q=", query); List<string> suggestionResult = new List<string>();
We will make a call to MakeRequest
on the _webRequest
object, passing on the endpoint as a parameter. If the call succeeds, we expect the JSON response to deserialize into a BingAutoSuggestResponse
object. This object will contain an array of suggestionGroups
, where each item contains an array of SearchSuggestions
.
Each item of SearchSuggestion
contains a URL, display text, a query string, and a search kind. We are interested in the display text, which we add to the suggestionResult
list. This list is returned to the caller:
try { BingAutoSuggestResponse response = await _webRequest.MakeRequest<BingAutoSuggestResponse>(endpoint); if (response == null || response.suggestionGroups.Length == 0) return suggestionResult; foreach(Suggestiongroup suggestionGroup in response.suggestionGroups) { foreach(Searchsuggestion suggestion in suggestionGroup.searchSuggestions) { suggestionResult.Add(suggestion.displayText); } } } catch(Exception ex) { Debug.WriteLine(ex.Message); } return suggestionResult;
For a complete description of response data, go to https://msdn.microsoft.com/en-us/library/mt711395.aspx#suggestions.
In the MainViewModel.cs
file, we want to get suggestions as we type. We will create a new function, as follows:
private async void GetAutosuggestions() { var results = await _autoSuggest.Suggest(SearchQuery); if (results == null || results.Count == 0) return; Suggestions = results; }
This will call the newly created Suggest
function, with the current value of the SearchQuery
. If any results are returned, we assign them to the SuggestionsIEnumerable
that we created earlier. Make sure to call this function when we set the value in the SearchQuery
property.
In the UI, this will have the first suggestion automatically populated in the search-query field. This is not ideal for users, but it will do for our test example.
18.188.178.181