TL;DR: Discover ways to combine good AI-based looking out into the .NET MAUI ComboBox utilizing customized filters and Semantic Kernel. The tutorial walks you thru making a customized filtering logic to deal with spelling errors or incomplete inputs, making certain extra correct search outcomes. Moreover, it covers integrating Semantic Kernel for superior AI-powered filtering, enhancing the person expertise in data-driven functions.
Introduction
The .NET MAUI ComboBox management is a flexible choice element that lets customers kind a price or choose an possibility from a predefined checklist. It’s designed to show options from giant datasets primarily based on person enter effectively.
On this weblog, we’ll display find out how to implement good AI-powered looking out, permitting the ComboBox to return correct outcomes, even when there are not any actual matches, by integrating the .NET MAUI ComboBox with Semantic Kernel.
Implementing the Sensible AI Looking
To implement good AI looking out, we’ll use the customized filtering characteristic of the .NET MAUI ComboBox management. We’ll first stroll you thru implementing customized filtering after which combine AI-driven search. For this demonstration, we use Semantic Kernel, a superb instrument for incorporating AI into .NET functions.
Customized filtering
The .NET MAUI ComboBox management means that you can apply customized filter logic to recommend objects that meet particular standards, leveraging the FilterBehavior property.
Step 1: Creating the Enterprise Mannequin for Meals Search
First, create a easy enterprise mannequin for meals search. Under is an instance of find out how to outline it:
// Mannequin.cs
public class FoodModel
{
public string? Identify { get; set; }
}
Subsequent, create the ViewModel, which accommodates a set of meals objects.
// ViewModel.cs
public class FoodViewModel : INotifyPropertyChanged
{
personal ObservableCollection meals;
public ObservableCollection Meals
{
get { return meals; }
set { meals = worth; OnPropertyChanged(nameof(Meals)); }
}
public FoodViewModel()
{
meals = new ObservableCollection
{
new FoodModel { Identify = "Acai Bowl" },
new FoodModel { Identify = "Aloo Gobi" },
new FoodModel { Identify = "Arepas" },
new FoodModel { Identify = "Baba Ganoush" },
// Extra meals objects...
};
}
public occasion PropertyChangedEventHandler? PropertyChanged;
protected digital void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Step 2: Making a Customized Filter Class
Now, create a category that implements the IComboBoxFilterBehavior interface. This class will outline customized filtering logic.
public class ComboBoxCustomFilter: IComboBoxFilterBehavior { }
Step 3: Implementing the GetMatchingIndexes Technique
Subsequent, implement the GetMatchingIndexes methodology from the IComboBoxFilterBehavior interface to create a suggestion checklist. This checklist will embody the filtered objects primarily based in your customized logic and might be displayed within the drop-down of the .NET MAUI ComboBox management. This methodology takes the next arguments:
- supply: This argument refers back to the ComboBox that owns the filter conduct. It offers entry to properties like ItemsSource and different related information.
- filterInfo: This argument accommodates the textual content entered by the person within the ComboBox. You should use this enter to generate a filtered suggestion checklist that can seem within the drop-down.
Under is an instance of filtering and displaying an inventory of meals within the ComboBox. The checklist exhibits solely the meals objects that begin with the textual content entered by the person:
public class ComboBoxCustomFilter : IComboBoxFilterBehavior
{
public async Activity<object?> GetMatchingIndexes(SfComboBox supply, ComboBoxFilterInfo filterInfo)
{
IEnumerable? itemssource = supply.ItemsSource as IEnumerable;
var filteredItems = from FoodModel merchandise in itemssource
the place merchandise.Identify.StartsWith(filterInfo.Textual content, StringComparison.CurrentCultureIgnoreCase)
choose merchandise;
return await Activity.FromResult(filteredItems);
}
}</object?>
Step 4: Making use of Customized Filtering to ComboBox
Lastly, bind the customized filter to the ComboBox management utilizing the FilterBehavior property.
<ContentPage.BindingContext> <native:FoodViewModel /> </ContentPage.BindingContext> <VerticalStackLayout> <syncfusion:SfTextInputLayout Trace="Select Meals Merchandise" ContainerType="Outlined" WidthRequest="248" ContainerBackground="Clear"> <editors:SfComboBox x:Identify="combobox" DropDownPlacement="Backside" MaxDropDownHeight="200" IsEditable="True" TextSearchMode="StartsWith" IsFilteringEnabled="True" DisplayMemberPath="Identify" TextMemberPath="Identify" ItemsSource="{Binding Meals}"> <editors:SfComboBox.FilterBehavior> <native:ComboBoxCustomFilter/> </editors:SfComboBox.FilterBehavior> </editors:SfComboBox> </syncfusion:SfTextInputLayout> </VerticalStackLayout>
The next picture demonstrates the output of the above customized filtering pattern.
Integrating Semantic Kernel along with your .NET MAUI app
Semantic Kernel is an open-source software program improvement equipment (SDK) created by Microsoft, designed to assist builders construct clever functions powered by giant language fashions (LLMs). This SDK simplifies the mixing of LLMs like OpenAI, Azure OpenAI, Google, and Hugging Face Transformers into conventional programming environments.
On this instance, we’ll deal with utilizing Azure OpenAI, however you may select any chat completion service. In the event you’re choosing Azure OpenAI, guarantee you’ve entry and arrange a deployment by way of the Azure portal. For directions, discuss with the Create and Deploy Azure OpenAI Service Information.
On this weblog, we’re utilizing the Semantic Kernel NuGet bundle, accessible within the NuGet Gallery. Earlier than beginning, set up this bundle in your .NET MAUI software to proceed with the mixing.
Organising Semantic Kernel
Now, let’s start creating the Semantic Kernel and Chat completion.
Step 1: Putting in Semantic Kernel
Start by putting in the Semantic Kernel NuGet bundle in your .NET MAUI software.
Step 2: Set up the Needed NuGet Packages
Then, set up the required NuGet packages and embody the suitable namespaces outlined on this getting began documentation.
Set up-Bundle Microsoft.SemanticKernel
Step 3: Setting Up Semantic Kernel
On this setup, we’ll make the most of Azure OpenAI with the GPT-35 mannequin, particularly deployed beneath the identify GPT35Turbo. To ascertain a profitable connection to the service, change the endpoint, deployment identify, and key along with your particular particulars.
Step 4: Chat Completion and Filtering
Now, you may make the most of the Chat completion characteristic to outline the chat historical past. The ChatHistory contains messages from the system, person, and assistant. In our software, we’ve got used the next messages as enter:
- System Message: Act as a filtering assistant.
- Person Message: Filter the checklist objects primarily based on the person enter utilizing characters beginning with phonetic algorithms like Soundex or Damerau-Levenshtein Distance. ” +r$” The filter ought to ignore spelling errors and be case insensitive.
Step 5: Using Chat Completion
Subsequent, make the most of the chat completion characteristic to acquire completion outcomes utilizing the GetChatMessageContentAsync methodology. We have now beforehand outlined the ChatHistory format for the AI response, permitting us to obtain the correctly formatted response message.
Under is the entire code for the ComboBoxAzureAIService class. Observe that I’ve commented out the Google Gemini codes. In the event you want to use them, merely uncomment the GetGoogleGeminiAIKernel methodology.
public class ComboBoxAzureAIService
{
personal const string endpoint = "https://YOUR_ACCOUNT.openai.azure.com/";
personal const string deploymentName = "GPT35Turbo";
personal const string key = "";
personal IChatCompletionService? _chatCompletion;
personal Kernel? _kernel;
personal ChatHistory? _chatHistory;
inside bool IsCredentialValid = false;
personal Uri? _uriResult;
public ComboBoxAzureAIService()
{
ValidateCredential();
}
personal async void ValidateCredential()
{
#area Azure OpenAI
// Use beneath methodology for Azure Open AI
this.GetAzureOpenAIKernel();
#endregion
#area Google Gemini
// Use beneath methodology for Google Gemini
// this.GetGoogleGeminiAIKernel();
#endregion
bool isValidUri = Uri.TryCreate(endpoint, UriKind.Absolute, out _uriResult)
&& (_uriResult.Scheme == Uri.UriSchemeHttp || _uriResult.Scheme == Uri.UriSchemeHttps);
if (!isValidUri || !endpoint.Comprises("http") || string.IsNullOrEmpty(key)
|| key.Comprises("API key") || string.IsNullOrEmpty(deploymentName)
|| deploymentName.Comprises("deployment identify"))
{
ShowAlertAsync();
return;
}
attempt
{
if (_chatHistory != null && _chatCompletion != null)
{
// Take a look at the semantic kernel with message
_chatHistory.AddSystemMessage("Whats up, Take a look at Examine");
await _chatCompletion.GetChatMessageContentAsync(chatHistory: _chatHistory, kernel: _kernel);
}
}
catch (Exception)
{
// Deal with any exceptions that point out the credentials or endpoint are invalid.
ShowAlertAsync();
return;
}
IsCredentialValid = true;
}
#area Azure OpenAI
personal void GetAzureOpenAIKernel()
{
// Create the chat historical past
_chatHistory = new ChatHistory();
attempt
{
var builder = Kernel.CreateBuilder()
.AddAzureOpenAIChatCompletion(deploymentName, endpoint, key);
// Get the kernel from construct
_kernel = builder.Construct();
// Get the chat completion from kernel
_chatCompletion = _kernel.GetRequiredService();
}
catch (Exception)
{
return;
}
}
#endregion
#area Google Gemini
personal void GetGoogleGeminiAIKernel()
{
// Add bundle Microsoft.SemanticKernel.Connectors.Google
// _chatHistory = new ChatHistory();
// IKernelBuilder _kernelBuilder = Kernel.CreateBuilder();
// _kernelBuilder.AddGoogleAIGeminiChatCompletion(modelId: "NAME_OF_MODEL", apiKey: key);
// Kernel _kernel = _kernelBuilder.Construct();
// _chatCompletion = _kernel.GetRequiredService();
}
#endregion
personal async void ShowAlertAsync()
{
if (Utility.Present?.MainPage != null && !IsCredentialValid)
{
await Utility.Present.MainPage.DisplayAlert("Alert",
"The Azure API key or endpoint is lacking or incorrect. Please confirm your credentials. " +
"You may also proceed with the offline information.", "OK");
}
}
public async Activity GetCompletion(string immediate, CancellationToken cancellationToken)
{
if (_chatHistory != null && _chatCompletion != null)
{
if (_chatHistory.Rely > 5)
{
_chatHistory.RemoveRange(0, 2); // Take away the message historical past to keep away from exceeding the token restrict
}
_chatHistory.AddUserMessage(immediate);
attempt
{
cancellationToken.ThrowIfCancellationRequested();
var chatResponse = await _chatCompletion.GetChatMessageContentAsync(chatHistory: _chatHistory, kernel: _kernel);
cancellationToken.ThrowIfCancellationRequested();
_chatHistory.AddAssistantMessage(chatResponse.ToString());
return chatResponse.ToString();
}
catch (RequestFailedException ex)
{
Debug.WriteLine($"Request failed: {ex.Message}");
throw;
}
catch (Exception ex)
{
Debug.WriteLine($"An error occurred: {ex.Message}");
throw;
}
}
return "";
}
}
Connecting to Semantic Kernel
Our .NET MAUI software can connect with the Semantic Kernel chat completion service by means of a customized filtering class. This practice filtering class makes use of the GetMatchingIndexes methodology, which is triggered every time enter textual content is entered into the .NET MAUI ComboBox management. By connecting to the Semantic Kernel chat completion service, we generate a immediate primarily based on the enter textual content and retrieve the response message, which is then transformed into an output assortment.
To ascertain this connection, we’ll modify the prevailing ComboBoxFilterBehavior to combine with the Semantic Kernel chat completion service. Under is the implementation of the ComboBoxCustomFilter class.
public class ComboBoxCustomFilter : IComboBoxFilterBehavior
{
personal readonly ComboBoxAzureAIService _azureAIService;
public ObservableCollection Gadgets { get; set; }
public ObservableCollection FilteredItems { get; set; } = new ObservableCollection();
personal CancellationTokenSource? _cancellationTokenSource;
public ComboBoxCustomFilter()
{
_azureAIService = new ComboBoxAzureAIService();
Gadgets = new ObservableCollection();
_cancellationTokenSource = new CancellationTokenSource();
}
public async Activity<object?> GetMatchingIndexes(SfComboBox supply, ComboBoxFilterInfo filterInfo)
{
Gadgets = (ObservableCollection)supply.ItemsSource;
// If credential is just not legitimate, the filtering information exhibits as empty
if (!_azureAIService.IsCredentialValid || string.IsNullOrEmpty(filterInfo.Textual content))
{
_cancellationTokenSource?.Cancel();
FilteredItems.Clear();
return await Activity.FromResult(FilteredItems);
}
string listItems = string.Be a part of(", ", Gadgets!.Choose(c => c.Identify));
// Be a part of the primary 5 objects with newline characters for demo output template for AI
string outputTemplate = string.Be a part of("n", Gadgets.Take(5).Choose(c => c.Identify));
// Cancel the earlier token if the person sorts repeatedly
_cancellationTokenSource?.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = _cancellationTokenSource.Token;
// Passing the Person Enter, ItemsSource, Reference output, and CancellationToken
var filteredItems = await FilterItemsUsingAzureAI(filterInfo.Textual content, listItems, outputTemplate, cancellationToken);
return await Activity.FromResult(filteredItems);
}
public async Activity<observablecollection> FilterItemsUsingAzureAI(string userInput, string itemsList, string outputTemplate, CancellationToken cancellationToken)
{
if (!string.IsNullOrEmpty(userInput))
{
var immediate = $"Filter the checklist objects primarily based on the person enter utilizing character beginning with and phonetic algorithms like Soundex or Damerau-Levenshtein Distance. " +
$"The filter ought to ignore spelling errors and be case insensitive. " +
$"Return solely the filtered objects with every merchandise on a brand new line with none further content material like explanations, hyphens, numberings, and minus indicators. Ignore phrases like 'Listed below are the filtered objects.' " +
$"Solely return objects which are current within the Listing Gadgets. " +
$"Be certain that every filtered merchandise is returned in its entirety with out lacking any a part of its content material. " +
$"Organize the filtered objects in order that these beginning with the person enter's first letter seem on the prime, adopted by different matches. " +
$"The instance information is for reference; don't present it as output. Filter the objects from the checklist correctly. " +
$"Right here is the Person enter: {userInput}, " +
$"Listing of Gadgets: {itemsList}. " +
$"If no objects are discovered, return 'Empty'. " +
$"Don't embody 'Listed below are the filtered objects:' within the output. Examine this demo output template, and return output like this: {outputTemplate}.";
var completion = await _azureAIService.GetCompletion(immediate, cancellationToken);
var filteredItems = completion.Cut up('n')
.Choose(x => x.Trim())
.The place(x => !string.IsNullOrEmpty(x))
.ToList();
if (FilteredItems.Rely > 0)
FilteredItems.Clear();
FilteredItems.AddRange(
Gadgets.The place(i => filteredItems.Any(merchandise => i.Identify!.StartsWith(merchandise)))
);
cancellationToken.ThrowIfCancellationRequested();
}
return FilteredItems;
}
}</observablecollection</object?>
The picture beneath illustrates the outcomes of an AI-based search utilizing customized filters.
GitHub reference
For extra particulars, discuss with the Sensible AI Search GitHub demo.
Attempt It Free
Conclusion
Thanks for studying! On this weblog, we explored find out how to implement a sensible AI search that delivers seamless outcomes, even when there are not any actual matches, utilizing the .NET MAUI ComboBox management. Attempt the steps shared right here and go away suggestions within the feedback part beneath!
This characteristic is on the market within the newest 2024 Quantity 3 launch. You’ll be able to take a look at all of the options in our Launch Notes and What’s New pages.
You’ll be able to obtain and take a look at our MAUI demo app from Google Play and the Microsoft Shops.
The present clients can obtain the brand new model of Important Studio on the License and Downloads web page. If you’re not a Syncfusion buyer, attempt our 30-day free trial to take a look at our unimaginable options.
You may also contact us by means of our help discussion board, help portal, or suggestions portal. We’re at all times comfortable to help you!