Data Binding in .NET MAUI AI AssistView (SfAIAssistView)
27 Jun 202522 minutes to read
Generate the assist request & response items
To add an AssistItem to the ViewModel.AssistItems
collection with specific values for profile details, text, and the IsRequested property, follow the steps below:
-
Start by creating an instance of the AssistItem class. This item will represent either a user request or a response received from the AI service.
-
The Assist item has the following members, which provides information for the request/response items,
- Profile: Provides information for the user details.
- Text: Describes the text content of the assist item (e.g., the request text from the user or the response text from the AI).
-
IsRequested: When the assist item represents a user request, set the
IsRequested
property toTrue
. If it’s a response item from the AI service, setIsRequested
toFalse
. - DateTime: To display item created or received time.
-
RequestItem: Used to hold data (request item) associated with response item. Default value is
null
.
-
After setting the properties, add the
AssistItem
instance to theViewModel.AssistItems
collection, which binds to theSfAIAssistView.AssistItems
property.
NOTE
The IsRequested property is automatically set to
True
, indicating it is a request from the user. If you want to manually add a request item through code, ensure you explicitly set theIsRequested
property toTrue
.
Additionally, use the CurrentUser property to specify the requester in theSfAIAssistView
.
public class ViewModel : INotifyPropertyChanged
{
. . .
public ObservableCollection<IAssistItem> AssistItems
{
get
{
return this.assistItems;
}
set
{
this.assistItems = value;
RaisePropertyChanged("AssistItems");
}
}
public ICommand AssistViewRequestCommand { get; set; }
public ViewModel()
{
this.assistItems = new ObservableCollection<IAssistItem>();
this.AssistViewRequestCommand = new Command<object>(ExecuteRequestCommand);
}
private async void ExecuteRequestCommand(object obj)
{
var request = (obj as Syncfusion.Maui.AIAssistView.RequestEventArgs).RequestItem;
await this.GetResult(request).ConfigureAwait(true);
}
private async Task GetResult(object inputQuery)
{
await Task.Delay(1000).ConfigureAwait(true);
AssistItem request = (AssistItem)inputQuery;
if (request != null)
{
// Generating response from AI
var userAIPrompt = this.GetUserAIPrompt(request.Text);
var response = await azureAIService!.GetResultsFromAI(request.Text, userAIPrompt).ConfigureAwait(true);
// Creating response item using response received from AI
AssistItem responseItem = new AssistItem() { Text = response };
responseItem.RequestItem = inputQuery;
this.AssistItems.Add(responseItem);
}
}
...
}
NOTE
The
SfAIAssistView.AssistItems
property is of typeIList<IAssistItem>
. To ensure the AssistItems property functions correctly, it is recommended to use a collection property in the ViewModel with the same type, such asObservableCollection<IAssistItem>
.
Binding custom model collection
The SfAIAssistView control provides support for binding collection of custom data objects through the ItemsSource property. This feature allows users to use their own data objects with the control. The ItemsSource
property binds a collection of custom data objects to the SfAIAssistView
and each item in the collection will be converted to an AssistItem
and displayed in the view. The ItemsSourceConverter property sets the converter used to transform data objects into assist items and vice versa.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.AIAssistView;assembly=Syncfusion.Maui.AIAssistView"
xmlns:local="clr-namespace:MauiAssistView"
x:Class="MauiAssistView.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<local:AssistItemConverter x:Key="converter" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.BindingContext>
<local:ViewModel x:Name="viewModel"/>
</ContentPage.BindingContext>
<syncfusion:SfAIAssistView x:Name="assistView"
ItemsSource="{Binding AssistItemsCollection}"
ItemsSourceConverter="{Binding converter}" />
</ContentPage>
SfAIAssistView assistView;
ViewModel viewModel;
AssistItemConverter assistItemConverter;
public MainPage()
{
InitializeComponent();
assistView = new SfAIAssistView();
viewModel = new ViewModel();
assistItemConverter = new AssistItemConverter();
assistView.ItemsSource = viewModel.AssistItems;
assistView.ItemsSourceConverter = assistItemConverter;
Content = assistView;
}
Create the below collection of objects that must be converted to assist items collection and displayed as items in SfAIAssistView
.
public class ItemModel : INotifyPropertyChanged
{
private string? prompt;
private string? response;
private object? promptItem;
private bool isRequested;
public string? Prompt
{
get { return prompt; }
set
{
prompt = value;
RaisePropertyChanged(nameof(Prompt));
}
}
public string? Response
{
get { return response; }
set
{
response = value;
RaisePropertyChanged(nameof(Response));
}
}
public bool IsRequested
{
get { return isRequested; }
set
{
isRequested = value;
RaisePropertyChanged(nameof(IsRequested));
}
}
public object? PromptItem
{
get { return promptItem; }
set
{
promptItem = value;
RaisePropertyChanged(nameof(PromptItem));
}
}
// Declare the PropertyChanged event.
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="propertyName">The name of the property that changed.</param>
protected virtual void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
NOTE
If you want your data objects to respond to property changes, then implement INotifyPropertyChanged interface in your model class.
public class ViewModel : INotifyPropertyChanged
{
#region Fields
ObservableCollection<ItemModel> assistItemsCollection;
#endregion
#region Constructor
public ViewModel()
{
assistItemsCollection = new ObservableCollection<ItemModel>();
this.GenerateAssistItems();
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the collection of messages of a conversation.
/// </summary>
public ObservableCollection<ItemModel> AssistItemsCollection
{
get
{
return assistItemsCollection;
}
set
{
assistItemsCollection = value;
RaisePropertyChanged(nameof(AssistItemsCollection));
}
}
#endregion
...
#region Item Generation
private async void GenerateAssistItems()
{
// Adding a request item
ItemModel requestItem = new ItemModel()
{
Prompt = "Types of listening",
IsRequested = true
};
// Add the request item to the collection
this.assistItemsCollection.Add(requestItem);
// Generating response item
await GetResult(requestItem);
}
private async Task GetResult(ItemModel requestItem)
{
await Task.Delay(1000).ConfigureAwait(true);
ItemModel responseItem = new ItemModel()
{
Response = "Types of Listening : For a good communication, it is not only enough to convey the information efficiently, but it also needs to include good listening skill. Common types of Listening are Active listening and Passive listening.",
IsRequested = false,
PromptItem = requestItem,
};
// Add the response item to the collection
this.assistItemsCollection.Add(responseItem);
}
#endregion
}
This converter must implement the IAssistItemConverter interface. Implement this interface to create a custom converter for the ItemsSourceConverter
property.
public class AssistItemConverter : IAssistItemConverter
{
public IAssistItem ConvertToAssistItem(object customItem, SfAIAssistView assistView)
{
var assistItem = new AssistItem();
var item = customItem as ItemModel;
if (item != null)
{
assistItem.Data = item;
assistItem.IsRequested = item.IsRequested;
if (item.IsRequested)
{
if (item.Prompt != null)
{
assistItem.Text = item.Prompt;
}
}
else
{
if (item.Response != null)
{
assistItem.Text = item.Response;
}
}
}
return assistItem;
}
public object ConvertToData(object assistViewItem, SfAIAssistView assistView)
{
var item = new ItemModel();
var assistItem = assistViewItem as AssistItem;
if (assistItem != null)
{
item.IsRequested = assistItem.IsRequested;
if (item.IsRequested)
{
item.Prompt = assistItem.Text;
}
else
{
item.Response = assistItem.Text;
}
}
return item;
}
}
NOTE
The
Data
property inAssistItem
holds a reference to the original data object which is used for data operations.
NOTE
Bind the RequestCommand property
The SfAIAssistView control allows you to handle user requests by binding them to the RequestCommand property. This command is triggered whenever the user sends a request in the assist view.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:syncfusion="clr-namespace:Syncfusion.Maui.AIAssistView;assembly=Syncfusion.Maui.AIAssistView"
xmlns:local="clr-namespace:MauiAIAssistView.ViewModel"
x:Class="MauiAIAssistView.MainPage">
<ContentPage.BindingContext>
<local:ViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<syncfusion:SfAIAssistView x:Name="sfAIAssistView"
AssistItems="{Binding AssistItems}"
RequestCommand="{Binding AssistViewRequestCommand}"/>
</ContentPage.Content>
</ContentPage>
using MauiAIAssistView.ViewModel;
using Syncfusion.Maui.SfAIAssistView;
namespace MauiAIAssistView
{
public partial class MainPage : ContentPage
{
SfAIAssistView sfAIAssistView;
ViewModel viewModel;
public MainPage()
{
InitializeComponent();
sfAIAssistView = new SfAIAssistView();
viewModel = new ViewModel();
this.sfAIAssistView.AssistItems = viewModel.AssistItems;
sfAIAssistView.SetBinding(SfAIAssistView.RequestCommandProperty, new Binding("AssistViewRequestCommand"));
this.Content = sfAIAssistView;
}
}
}